From 25635b5ccb327329b48ecedfa7822778677147e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20G=C3=B6ttsch?= Date: Sat, 20 Jul 2024 23:36:28 +0200 Subject: [PATCH 01/10] [imp] add sale order name to batch view --- sale_order_batch/views/sale_order_batch_views.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/sale_order_batch/views/sale_order_batch_views.xml b/sale_order_batch/views/sale_order_batch_views.xml index 2eb1ecc..d4fdabe 100644 --- a/sale_order_batch/views/sale_order_batch_views.xml +++ b/sale_order_batch/views/sale_order_batch_views.xml @@ -79,6 +79,7 @@ attrs="{'readonly': [('state', 'in', ('closed'))]}" > + From a5ff47bb10cd45457433663a6133a075165dc671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20G=C3=B6ttsch?= Date: Sun, 21 Jul 2024 00:07:20 +0200 Subject: [PATCH 02/10] =?UTF-8?q?[imp]=20add=20nfu=5Fsale=5Forder=5Fpackag?= =?UTF-8?q?ing=20and=20m=C2=B4port=20max=20min=20fields?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nfu_sale_order_packaging/README.rst | 67 +++ nfu_sale_order_packaging/__init__.py | 1 + nfu_sale_order_packaging/__manifest__.py | 11 + nfu_sale_order_packaging/models/__init__.py | 1 + .../models/sale_order_line.py | 15 + .../readme/CONTRIBUTORS.rst | 2 + .../readme/DESCRIPTION.rst | 2 + nfu_sale_order_packaging/readme/HISTORY.rst | 1 + .../static/description/icon.png | Bin 0 -> 12282 bytes .../static/description/index.html | 430 ++++++++++++++++++ .../views/sale_order_batch_views.xml | 17 + .../views/sale_order_views.xml | 14 + 12 files changed, 561 insertions(+) create mode 100644 nfu_sale_order_packaging/README.rst create mode 100644 nfu_sale_order_packaging/__init__.py create mode 100644 nfu_sale_order_packaging/__manifest__.py create mode 100644 nfu_sale_order_packaging/models/__init__.py create mode 100644 nfu_sale_order_packaging/models/sale_order_line.py create mode 100644 nfu_sale_order_packaging/readme/CONTRIBUTORS.rst create mode 100644 nfu_sale_order_packaging/readme/DESCRIPTION.rst create mode 100644 nfu_sale_order_packaging/readme/HISTORY.rst create mode 100644 nfu_sale_order_packaging/static/description/icon.png create mode 100644 nfu_sale_order_packaging/static/description/index.html create mode 100644 nfu_sale_order_packaging/views/sale_order_batch_views.xml create mode 100644 nfu_sale_order_packaging/views/sale_order_views.xml diff --git a/nfu_sale_order_packaging/README.rst b/nfu_sale_order_packaging/README.rst new file mode 100644 index 0000000..c9230a0 --- /dev/null +++ b/nfu_sale_order_packaging/README.rst @@ -0,0 +1,67 @@ +======================== +NFU Sale Order Packaging +======================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:cf35c3a80aa0718148099036cd6a3dd60afb61acdb420573b1bd129be3ea2cf1 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-bruecksen%2Fife_nfu-lightgray.png?logo=github + :target: https://github.com/bruecksen/ife_nfu/tree/16.0/nfu_sale_order_packaging + :alt: bruecksen/ife_nfu + +|badge1| |badge2| |badge3| + +This module adds a minium and a maximum order quantity field to Sale Orders +and adds a packaging default to sale order batch. + +**Table of contents** + +.. contents:: + :local: + +Changelog +========= + +:1.0.0: Initial module. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* BAKEUP + +Contributors +~~~~~~~~~~~~ + +* Niels Göttsch +* Matthias Brück + +Maintainers +~~~~~~~~~~~ + +This module is part of the `bruecksen/ife_nfu `_ project on GitHub. + +You are welcome to contribute. diff --git a/nfu_sale_order_packaging/__init__.py b/nfu_sale_order_packaging/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/nfu_sale_order_packaging/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/nfu_sale_order_packaging/__manifest__.py b/nfu_sale_order_packaging/__manifest__.py new file mode 100644 index 0000000..8e81c8b --- /dev/null +++ b/nfu_sale_order_packaging/__manifest__.py @@ -0,0 +1,11 @@ +{ + "name": "NFU Sale Order Packaging", + "summary": "Add minimum and maximum order quantities to sale orders and use default packaging", + "author": "BAKEUP", + "website": "https://www.bakeup.org", + "category": "Stock", + "version": "16.0.0.0.1", + "depends": ["sale", "sale_order_batch"], + "data": ["views/sale_order_views.xml", "views/sale_order_batch_views.xml"], + "license": "LGPL-3", +} diff --git a/nfu_sale_order_packaging/models/__init__.py b/nfu_sale_order_packaging/models/__init__.py new file mode 100644 index 0000000..8eb9d1d --- /dev/null +++ b/nfu_sale_order_packaging/models/__init__.py @@ -0,0 +1 @@ +from . import sale_order_line diff --git a/nfu_sale_order_packaging/models/sale_order_line.py b/nfu_sale_order_packaging/models/sale_order_line.py new file mode 100644 index 0000000..a0bd60b --- /dev/null +++ b/nfu_sale_order_packaging/models/sale_order_line.py @@ -0,0 +1,15 @@ +from odoo import _, api, fields, models +from odoo.exceptions import UserError + + +class SaleOrderLine(models.Model): + _inherit = "sale.order.line" + + product_uom_ordered_qty = fields.Float(string="Ordered Qty", digits="Product Unit of Measure", default=1.0) + product_uom_max_qty = fields.Float(string="Max Qty", digits="Product Unit of Measure") + + @api.constrains("product_uom_qty", "product_uom_max_qty") + def _check_product_uom_qty(self): + for record in self: + if record.product_uom_max_qty != 0 and record.product_uom_qty > record.product_uom_max_qty: + raise UserError(_("The quantity must be less than or equal to the maximum quantity.")) diff --git a/nfu_sale_order_packaging/readme/CONTRIBUTORS.rst b/nfu_sale_order_packaging/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000..a4ec453 --- /dev/null +++ b/nfu_sale_order_packaging/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Niels Göttsch +* Matthias Brück \ No newline at end of file diff --git a/nfu_sale_order_packaging/readme/DESCRIPTION.rst b/nfu_sale_order_packaging/readme/DESCRIPTION.rst new file mode 100644 index 0000000..3bd5ae9 --- /dev/null +++ b/nfu_sale_order_packaging/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +This module adds a minium and a maximum order quantity field to Sale Orders +and adds a packaging default to sale order batch. \ No newline at end of file diff --git a/nfu_sale_order_packaging/readme/HISTORY.rst b/nfu_sale_order_packaging/readme/HISTORY.rst new file mode 100644 index 0000000..765ab9c --- /dev/null +++ b/nfu_sale_order_packaging/readme/HISTORY.rst @@ -0,0 +1 @@ +:1.0.0: Initial module. \ No newline at end of file diff --git a/nfu_sale_order_packaging/static/description/icon.png b/nfu_sale_order_packaging/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..126771222c96d9acfa22f7f2d27f6f4b9ce7feb6 GIT binary patch literal 12282 zcmVV1@Qs7XSkRTxI|~Py5^#W+lo3 zI?bdpSwOrSzBS8Bt(s(0)Hvs$#!1ihg z;>r$p2yo{BI2XW30KWlHCyW5d0@?vU*7@a!0A2&I06=*Lfw(Gg`?UAk1GoXe^#D3n zD`2NFpaT{jIS0VAhJq)DH^dU0sfP|$;oP+W+yvkr4cI@$LX@i8UG>%DXi^OhdfckC#4bl?W zX#!}yQ~wKK0)V%&K(-aw9!+Am1uzc4%^Kj-!_?<+K#NV-1E9>{$j^Z7$5!c*J?sZ| zKLAe~ujwJJ9Smr_^A-Sj1i(7YYLNwUVmY=;lgxhr@Hl`1$4hGm0$P{K#Q+`zFjKQy z__NAhQh_Zl|2D?zc(tRYwZi}%&^Ymj0PX}kMY23OwTD-uA-907N(~$dY6n@-#T9$p z(6TQvz?`)uJ7;V>0Hy=z1>jTTe`k%210=LgF}?-6X4hn;a#~31Cjk7>Q4}P_fY!Zz zZy6Nhu%*+ohcmggjNhf;P=hAMn0Ygma)`F<2XGfSw%{<#W~1!k%tL5~7r^@f&H;zx zrd|-GNJ7g@J^t|z>qNJ&Pjt`i%>brB1&O(< zBcKJ$3jquVZ~M2;;}-}750KAi26iBj1vQcC51H&9Ta6PUpoW2W3Drm{sNKm0^ZNiU zH^6L990m~&irdX?^=jaeM}YqQfm2Qax^w|*rMX<7 z=bj7xUZ%7_0Oa?BjvN8??#+GDv?=J#H$(Sl{LO2;_9vo)1_t~IM;np@=J$*TblC#t zKtOf={{5iaZ&$$ec+5a{yFocQ{0e|(&B{zr%k#eVR`6uM_FB-MJ?gwbz;00YA)=#6 z0W}g2=1+;JhHYThf%u>QfZDg`LGgOk05xd>8Z<~rA_2O~1!~j?w0AELntcP8K2o~0 z6!h}Tpq4GUPo&?PHwVq0od{_ypdL&_r9>1+D5w(zXrJ-AoQUe!LNj!!Tv!MiIWkx( zw`&KQHVt&(fcoC&pMx4VW-#aG@_7>{@@EwlnFVOSU;X{ubE@y8UjWceH-UfadH@EO2P3qT8)HxN<2ZD5waXU_(;ZmsBq#{;Ta6EtcR=-|Q76X3n~`23t42KIU9 z1rKm_Z!&o+DnR$&&meZY6&14zhX4KF(ET5K6aDE1Z3PcF9ni9r6cJG;^T5e>0s%FUJ$k6`cI&2;q)eb0GO;&q1oi8ugn{(Ox#xoF)l>Z{ z?~fi0I(*npP>ZAyw~5DuP6ynKMBR8u0VisG<7r#TVH^q;6^|r;L5smpy25{ayH6Q}oF=LokSe3}L&H_F0 z1ZeJD9>{?M&E7-+bk9A`^(2M@mp=JE`pB$X$f|Vn&FoRtxwSmsHP@*AY1>v&ujDzN z1k}@Q;nRqpH;=PT35-?ox&C^yl(AYtPC13`*P#YT+~xv+yga5YPUF-13MGHb^ZWgv zapTl;i;daq<@U@oq0O4dj--g!q2pbX-;ah1m=2v2(of%hF$74(i(%^x%VP<(M@Kl%H>w%3`Vb-~*;uI;ivVKvSkD3H|uvYGw0y zK;M0r%9Tk#Jt;0ejo790n3PeCaFT1p2(!d#(}pc0K40iTlJ^%cR-kaXKx4-`2hd`I zeDFafbq5SE+m_{dJs!}cN$R_$rJzS2RX~^5!GqaZHDG|c#wn*HOA)NfK3$WDzKfZ9 zAT}_sOexg}rx+C$f=)WgZ1os1B0M;)c4|=|CF(5IfEMXoRK(Avo8ZJrBvyN0Qu^01D~O1mYE%$WkEB>NVxb;yza30H=FABm zEcv^%6m;sT3LK3as~{&QnC?VR*t(TXk^j(Pz=gK{$M~|`v$7;3|K+l}% zlvPPq{24KU8qrJVDUJiP6{N$5o4sSrnz7<2_G=lmvNF)+mzyP@(|5JJ{4%J1eY0hz zd2`T9FR7KvIuZ3}S+IcVg>IYA$zkQv8I~QlvFaBPQDM~a(-8vNZ(MjU5jD_$)Ol{- zK!AC3L4n!6eEs!inz3~&YyP4P0=$JwmTRXuR&oZ+-*7AZYCYAKEAr1L1pD1uc<={Md8rXCXG`}*q)cpc1r`+`bJoF7)IQ-bH7 zV=gSfyz8#e5r_Ju@cGz$r}xVpcR0;VDYoexLqUvON+WXVyx#Z$XG-T#puX%fvm(^4 zouVVUIqT9(IifFJf|GRT%KG)7o;}S{HWcO1sn(P!W}4*`B{;N#cu7e|6l0V(4oqVSF4r^%5vWG3)Vh~ zn0g>Gs<9&F4wP7>^fS+x!%Ri1@7`Sn>!kCBSsjGdXOPbpFJ|6N#1Qu~no|BlaGC`l)%9 zy6--xZx|LK`f)^38j(q7SK3Ht0qCevp<|v`u1r*773WRr@^Vh+p!b19oLUJ3MqK zr_;UlRt7Twy!IMUyS7TV>s&4k0J8ub42#P!5;_3jEO41M7qX?*VxLUXyLvCXT;`T4 zY5m3I9s39&_8X&sNt;1_ekzJG=@4V0-7Ny>Ja5L?Y@^u{MZ{S-M~^lqv(bZ~eN$cGkv}8$esA#rX zH`J~Titm8hFGxmef~IK~S(l2)wpU&;@A}X)6@|;67plp3B*ay|>+yglOi2G|z{Kuo zc_Jv~fk8RMy73`^OOVtuTxmuz_U{Moyc3u`+fYKh%1R;1Apq2>1$6BSbnXnaYX{V; z$1x=b4lphG{(E5kdf?C@GpCi`k!y_{2~3@;sEf;$9ScQ=djj~tfo70DB zl*3O%-P0=WIhkNywTgF-!%}feKs{)XN+53CRT8RMfw^%b=<2J3uWL;rnQ4WNst#D1 zX`&raK^{LCh|hMG70heaaDY54br3}|>p7QY?_MO^nIsLa9sxLgI;ZT?uP+m5-n`6> z7!1#&e`it*q3FgxveG$(0=Q)hmuWzlqMiU~*)l#?BKzXmWkUq|_+wD*+KPGz4Qbkx zizijKvpaK|7%e&yQQ0rakTlc%5;09@9VUiickCE&#T7tdp;Fj%XNUZ~VnzHxP;NK> zMnwg1{`tV1Im(MCUdX~iVA3S@UWWT;jn^Lm{P2t8#jX6~YqQ=#n7wqj-_Di@t0lt< z{BORo&jKMKoflmMj2owZS6<(EgWc(33CUVJ%-D6aMBWQvv*upRn&)QC;^y`8mMsDE zX{T|hrG9+-t(pXONKTnRk3Y`8r^j5BlrX4e;$`+B667nB9}&Ph0HwyinG0x%2j06E zxbHp%VtMV-1^DC>pk+(*_qJ{YcJEfM?YM`@xQ^EgJp8cvJ(mmk_+vBW$zXD5ynYRd zMKZeN8#BH$m^-`OEE$W6%n~;*k0o}qW(;frna2YhKMt&1X|L3j7>-LX1sXPFDJ}6I zYu7TL&T?t#>`maHf0rP5LzXuil6b=g;LSJ9yfqMDWvqL52GF2EW@!olOO}}bw?j$? z0ziWXyi;A?bGd*cM}QqWva~}<=)(ZEi%2E_TQZ(M%W^(p0&wDl3b^8H(s@TZ*ybm*X-&*cI(ZBo__yPvzDAedhtIAFH4 zBwYP+F{hW7sB1?bE-OpoMpmeSZ2%6$Eum#*$qngCuShPZDltMgUV9BFE8~uptx>=E z4KMj({qXsK8a05ygIO7rXY%=g`SXFEJ?#(9FDnavFDECteY1T#@Ylccdo^nUW5=?! zC!XzFa_z6b2LAa^zRpP}DMdKC<9nImbK?pZ4VAie|9(z7E~Oouoa9CBzqFL=l)zGX z_KPpfm0IO>{`}x`yLGcSfJlBziXrI%QBqGO(S0h{U$VsPCEc?}mB$nJeYCB#lwYOB z4Z!g-vBh-sB_bj(u+t*CqvxFfd$!(rhnL+$hnR2X<^s)|1Hb+?he3Aj>bwn^LN`{g zW<^WFH2r?y%rk*s{mQ)Zh~(|pkGD|m+o!&>em!5OcklRjn}~Pt#0g;4Ds`_!yh5~Z zZ?6(s)sd5JAAmJ8Peeb_ImZ$E&lS$X4)}zszI)iu2EBW#zyD(DCD}94=V`y5b6R znY9ZqbcU1`>GS#LDyUwh;N_QBevk6qIdjaCU6QM>UadCLzVHH9t&*5(Ys<~$Qfs%~ zsx}Gi-mS`M=mj<}y)?Of=X?pRWA|or)WO{7vwoh}%ZVE6 z*5!z~q9Tr?ww^Dmn{KZkHH!1*wP=xCy+it_eS6@QSHh2(*9**@3ydDk0G6FM66jS{ z28KmEcR)=39r842KAk%o(lesoF|1L z0oMEzWpfSXS{5EGR*K5FqSXy97717~B1Nj{>(&gNlgoR3`%0Sz;aoe%O zys5Xm9CZKv!G%o$=FsvSVhy|h{@~PVWo70PBC&Dk5#+XO7Q0+LD-7e2cS?knBa}_GtSmAcc1ej^iuGM3!k0xd%QNZ`YZ6^1&nioIK>^UC zhmw9`mtL`g!&{TNpHS$}x^=+mr*rGmho!K`18m;R{C>(5{y!&&SKr2sf%o16{{3&x zGL@I7?DA8lu(UpYocn6_Y^EHoTA5?bqd&@FOCVrrDVyQS%R}>DpO5*KPE!sYVh$`NO;#?)kLMVe z{{7iBs;3B>Fo7LYy?Q0rG3E2I(@2i|eBeL-0dBjE^`V>`ewK;~2K<|E0v$W@|5skg zCfeb{nP%0j$w1$|TRG;6i}||s>ctgt5xZN z8q-XQY;{@QbhEbY% z>{t~(5TDuZ212wo2txrn8jdLT#;UkwG6DVe+rjY?4?Yf z0raf|q8dp9bTlm)fR;{Pwk+87J#=VzDJY6ej~)tS0<@=}Hs5b3V28S1r~oGU-tghU zMKhCCbUqxQ^~v9^9cbxNbD?RX)=kkLmy2`Utyz;C^QKOV>eb`uN%_rK zo>!-EUAn|up@4p&9B!alR1#V`_^!LyJ-ulYhdkO5gCXC4{&{un@#7O4-ywrBa3Bwq zI70y5%co~35-=S-$~IK}Xwrmj$5jP1#kz{PT)YD4s|WxrUvAIp7-?{l-_JJs!-wsu zr|5RGt|F^)^ubA@`*{GI1TWA&rkT~SA-63%TBa0cx3-iTM5ZiR~XfmSf^X{+${%LOY{k6<|Y$ z0-t@x*N)vYoClyKyg+Q>O`$e=+Q}Icb?tCoKewAVy)Im6{%qz<2DHAc9zLuJzstSl z=bJrRkTerr(>__w4Em{DNJ{tb>c&^=~3AY%pVo2zd05pUfkW`w1sBcD0 zQi+gAiMn=Wl495}4rLU@%kAdk?n5PU3lfL4i4o62L1(d3jKohvFtmDNIx;_svDTdkO4}UO6%emda`|oogzF2c=)e3L^ zOXP9lL~s;f&6i1dEwA;ppN@`5c3b}z%B zj^oFJHzU-pZEs3}^gCn_I_n5NIV#g#we1?CZ^n*QOS-s~mn`8O8?vp)N-<*zE=$e2^U~ZQJrvuTO%* zhZC2YOMYYNQgxrg>CZUB4EoGG8Ubjd1G>8~!7Qo`08N?{Y`HjgjMM9ul&D?daugOa zsI64QE~SZxgW~1-(t7pE`2h1w8z7a zj2mxM)&>D@aWU_}u^Z6x`=5Qro=dquzn@Kv;<8U=O10E0glGREkd2ZQjSQ4$wqmGL z55FH6GX}Wi5)~FHR*yxCRMsfHO4j!6_5xb2Q&z@wN2ImxVQbu2xyCbBAv{}`*+MgV zW)(w=q$c8A5}i7!03=bqbkGWK7O$NhfEH(i$HN)z|L_0QL=&!l|NWUhN`7z*$CUlLC}6z#tC*6XX9}pl{u

W$<1~*|NZw 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 literal 0 HcmV?d00001 diff --git a/nfu_sale_order_packaging/static/description/index.html b/nfu_sale_order_packaging/static/description/index.html new file mode 100644 index 0000000..36dab75 --- /dev/null +++ b/nfu_sale_order_packaging/static/description/index.html @@ -0,0 +1,430 @@ + + + + + +NFU Sale Order Packaging + + + +

+

NFU Sale Order Packaging

+ + +

Beta License: LGPL-3 bruecksen/ife_nfu

+

This module adds a minium and a maximum order quantity field to Sale Orders +and adds a packaging default to sale order batch.

+

Table of contents

+ +
+

Changelog

+ +++ + + + +
1.0.0:Initial module.
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • BAKEUP
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is part of the bruecksen/ife_nfu project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/nfu_sale_order_packaging/views/sale_order_batch_views.xml b/nfu_sale_order_packaging/views/sale_order_batch_views.xml new file mode 100644 index 0000000..6b32222 --- /dev/null +++ b/nfu_sale_order_packaging/views/sale_order_batch_views.xml @@ -0,0 +1,17 @@ + + + + sale.order.batch.form.product.min_max_qty + sale.order.batch + + + + + + + + + diff --git a/nfu_sale_order_packaging/views/sale_order_views.xml b/nfu_sale_order_packaging/views/sale_order_views.xml new file mode 100644 index 0000000..f0d2742 --- /dev/null +++ b/nfu_sale_order_packaging/views/sale_order_views.xml @@ -0,0 +1,14 @@ + + + + sale.order.form.product.min_max_qty + sale.order + + + + + + + + + From 4569ce96551fc53accf264d12eca90d9ec1f7b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20G=C3=B6ttsch?= Date: Sun, 21 Jul 2024 00:42:24 +0200 Subject: [PATCH 03/10] [imp] add default packaging to sale order patch product --- nfu_sale_order_packaging/models/__init__.py | 1 + .../models/sale_order_batch_product.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 nfu_sale_order_packaging/models/sale_order_batch_product.py diff --git a/nfu_sale_order_packaging/models/__init__.py b/nfu_sale_order_packaging/models/__init__.py index 8eb9d1d..7b39236 100644 --- a/nfu_sale_order_packaging/models/__init__.py +++ b/nfu_sale_order_packaging/models/__init__.py @@ -1 +1,2 @@ from . import sale_order_line +from . import sale_order_batch_product diff --git a/nfu_sale_order_packaging/models/sale_order_batch_product.py b/nfu_sale_order_packaging/models/sale_order_batch_product.py new file mode 100644 index 0000000..06d9862 --- /dev/null +++ b/nfu_sale_order_packaging/models/sale_order_batch_product.py @@ -0,0 +1,15 @@ +from odoo import api, models + + +class SaleOrderBatchProduct(models.Model): + _inherit = "sale.order.batch.product" + + @api.model_create_multi + def create(self, vals_list): + for vals in vals_list: + + if vals.get("product_id") and not vals.get("product_packaging_id"): + product_id = vals.get("product_id") + packaging = self.env["product.packaging"].search([("product_id", "=", product_id)], limit=1) + vals["product_packaging_id"] = packaging.id + return super().create(vals_list) From 46bf4d5c1a74aabeb677ba03cf08b6c954fc2840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20G=C3=B6ttsch?= Date: Sun, 21 Jul 2024 01:25:19 +0200 Subject: [PATCH 04/10] [add] unfinisched packages warning --- .vscode/launch.json | 2 +- nfu_sale_order_packaging/__manifest__.py | 6 ++- .../models/sale_order_batch_product.py | 11 ++++- .../views/sale_order_batch_product_views.xml | 13 ++++++ sale_order_batch/__manifest__.py | 1 + .../models/sale_order_batch_product.py | 5 ++- .../views/sale_order_batch_product_views.xml | 42 +++++++++++++++++++ .../views/sale_order_batch_views.xml | 2 +- 8 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 nfu_sale_order_packaging/views/sale_order_batch_product_views.xml create mode 100644 sale_order_batch/views/sale_order_batch_product_views.xml diff --git a/.vscode/launch.json b/.vscode/launch.json index 874d31d..68c8234 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,7 +13,7 @@ "--addons-path=${config:odoo.addons_path},${workspaceFolder}", "--limit-time-real=0", "--limit-time-cpu=0", - "--init=sale_order_batch", + "--update=sale_order_batch,nfu_sale_order_packaging", // "--update=", "--dev=xml" ] diff --git a/nfu_sale_order_packaging/__manifest__.py b/nfu_sale_order_packaging/__manifest__.py index 8e81c8b..81a61c0 100644 --- a/nfu_sale_order_packaging/__manifest__.py +++ b/nfu_sale_order_packaging/__manifest__.py @@ -6,6 +6,10 @@ "category": "Stock", "version": "16.0.0.0.1", "depends": ["sale", "sale_order_batch"], - "data": ["views/sale_order_views.xml", "views/sale_order_batch_views.xml"], + "data": [ + "views/sale_order_views.xml", + "views/sale_order_batch_views.xml", + "views/sale_order_batch_product_views.xml", + ], "license": "LGPL-3", } diff --git a/nfu_sale_order_packaging/models/sale_order_batch_product.py b/nfu_sale_order_packaging/models/sale_order_batch_product.py index 06d9862..aef5f9d 100644 --- a/nfu_sale_order_packaging/models/sale_order_batch_product.py +++ b/nfu_sale_order_packaging/models/sale_order_batch_product.py @@ -1,9 +1,18 @@ -from odoo import api, models +from odoo import api, fields, models class SaleOrderBatchProduct(models.Model): _inherit = "sale.order.batch.product" + open_packaging_qty = fields.Float(compute="_compute_open_packagin_qty") + + @api.depends("sale_order_line_ids.product_uom_qty") + def _compute_open_packagin_qty(self): + for product in self: + product.open_packaging_qty = ( + sum(product.sale_order_line_ids.mapped("product_uom_qty")) % product.product_packaging_qty + ) + @api.model_create_multi def create(self, vals_list): for vals in vals_list: diff --git a/nfu_sale_order_packaging/views/sale_order_batch_product_views.xml b/nfu_sale_order_packaging/views/sale_order_batch_product_views.xml new file mode 100644 index 0000000..3542a6d --- /dev/null +++ b/nfu_sale_order_packaging/views/sale_order_batch_product_views.xml @@ -0,0 +1,13 @@ + + + + sale.order.batch.product.form.nfu + sale.order.batch.product + + + + + + + + diff --git a/sale_order_batch/__manifest__.py b/sale_order_batch/__manifest__.py index 2c1b66b..b88156b 100644 --- a/sale_order_batch/__manifest__.py +++ b/sale_order_batch/__manifest__.py @@ -9,6 +9,7 @@ "data": [ "data/ir_sequence_data.xml", "views/sale_order_batch_views.xml", + "views/sale_order_batch_product_views.xml", "views/sale_order_views.xml", "views/sale_menus.xml", "security/ir.model.access.csv", diff --git a/sale_order_batch/models/sale_order_batch_product.py b/sale_order_batch/models/sale_order_batch_product.py index 60a7d86..52d02ac 100644 --- a/sale_order_batch/models/sale_order_batch_product.py +++ b/sale_order_batch/models/sale_order_batch_product.py @@ -14,14 +14,15 @@ class SaleOrderBatchProduct(models.Model): ondelete="cascade", index=True, copy=False, + readonly=True, ) - product_id = fields.Many2one(comodel_name="product.product", required=True, readonly=False) + product_id = fields.Many2one(comodel_name="product.product", required=True, readonly=True) product_template_id = fields.Many2one( "product.template", related="product_id.product_tmpl_id", string="Product Template" ) - sale_order_line_ids = fields.Many2many("sale.order.line", compute="_compute_sale_order_line_ids") + sale_order_line_ids = fields.Many2many("sale.order.line", compute="_compute_sale_order_line_ids", store=True) product_uom_category_id = fields.Many2one(related="product_id.uom_id.category_id", depends=["product_id"]) product_uom_qty = fields.Float(compute="_compute_uom_qty") product_uom = fields.Many2one(related="product_id.uom_id") diff --git a/sale_order_batch/views/sale_order_batch_product_views.xml b/sale_order_batch/views/sale_order_batch_product_views.xml new file mode 100644 index 0000000..9b406ef --- /dev/null +++ b/sale_order_batch/views/sale_order_batch_product_views.xml @@ -0,0 +1,42 @@ + + + + sale.order.batch.product.form + sale.order.batch.product + +
+ +
+
+

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
diff --git a/sale_order_batch/views/sale_order_batch_views.xml b/sale_order_batch/views/sale_order_batch_views.xml index d4fdabe..9370be8 100644 --- a/sale_order_batch/views/sale_order_batch_views.xml +++ b/sale_order_batch/views/sale_order_batch_views.xml @@ -106,7 +106,7 @@ - + From 2c97b8a6b1e82827de147f1957a9780bd8c34302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20G=C3=B6ttsch?= Date: Sun, 21 Jul 2024 01:59:10 +0200 Subject: [PATCH 05/10] [add] added open packages to product view --- .../models/sale_order_batch_product.py | 7 ++++++- .../views/sale_order_batch_product_views.xml | 7 +++++++ .../views/sale_order_batch_views.xml | 9 +++++++++ sale_order_batch/models/sale_order_batch_product.py | 4 +++- .../views/sale_order_batch_product_views.xml | 4 +--- 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/nfu_sale_order_packaging/models/sale_order_batch_product.py b/nfu_sale_order_packaging/models/sale_order_batch_product.py index aef5f9d..c3f5535 100644 --- a/nfu_sale_order_packaging/models/sale_order_batch_product.py +++ b/nfu_sale_order_packaging/models/sale_order_batch_product.py @@ -9,8 +9,13 @@ class SaleOrderBatchProduct(models.Model): @api.depends("sale_order_line_ids.product_uom_qty") def _compute_open_packagin_qty(self): for product in self: + open_packaging_qty = product.product_packaging_qty - ( + sum(product.sale_order_line_ids.mapped("product_uom_qty")) + % product.product_packaging_qty + % product.product_packaging_qty + ) product.open_packaging_qty = ( - sum(product.sale_order_line_ids.mapped("product_uom_qty")) % product.product_packaging_qty + 0 if open_packaging_qty == product.product_packaging_qty else open_packaging_qty ) @api.model_create_multi diff --git a/nfu_sale_order_packaging/views/sale_order_batch_product_views.xml b/nfu_sale_order_packaging/views/sale_order_batch_product_views.xml index 3542a6d..564d876 100644 --- a/nfu_sale_order_packaging/views/sale_order_batch_product_views.xml +++ b/nfu_sale_order_packaging/views/sale_order_batch_product_views.xml @@ -8,6 +8,13 @@ + + + + diff --git a/nfu_sale_order_packaging/views/sale_order_batch_views.xml b/nfu_sale_order_packaging/views/sale_order_batch_views.xml index 6b32222..aa7516b 100644 --- a/nfu_sale_order_packaging/views/sale_order_batch_views.xml +++ b/nfu_sale_order_packaging/views/sale_order_batch_views.xml @@ -12,6 +12,15 @@ + + + + + (open_packaging_qty != 0) + diff --git a/sale_order_batch/models/sale_order_batch_product.py b/sale_order_batch/models/sale_order_batch_product.py index 52d02ac..cc2b387 100644 --- a/sale_order_batch/models/sale_order_batch_product.py +++ b/sale_order_batch/models/sale_order_batch_product.py @@ -22,7 +22,9 @@ class SaleOrderBatchProduct(models.Model): product_template_id = fields.Many2one( "product.template", related="product_id.product_tmpl_id", string="Product Template" ) - sale_order_line_ids = fields.Many2many("sale.order.line", compute="_compute_sale_order_line_ids", store=True) + sale_order_line_ids = fields.Many2many( + "sale.order.line", compute="_compute_sale_order_line_ids", store=True, readonly=False + ) product_uom_category_id = fields.Many2one(related="product_id.uom_id.category_id", depends=["product_id"]) product_uom_qty = fields.Float(compute="_compute_uom_qty") product_uom = fields.Many2one(related="product_id.uom_id") diff --git a/sale_order_batch/views/sale_order_batch_product_views.xml b/sale_order_batch/views/sale_order_batch_product_views.xml index 9b406ef..90a273e 100644 --- a/sale_order_batch/views/sale_order_batch_product_views.xml +++ b/sale_order_batch/views/sale_order_batch_product_views.xml @@ -23,11 +23,9 @@ - + - - From b8991d6b2be1933048c0ba81372c20de1fe703c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20G=C3=B6ttsch?= Date: Tue, 23 Jul 2024 20:40:07 +0200 Subject: [PATCH 06/10] [fix] clean up .vscode files --- .vscode/launch.json | 10 +++++----- .vscode/settings.json | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 68c8234..f7805af 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,12 +9,12 @@ "program": "${config:odoo.path}/odoo-bin", "console": "integratedTerminal", "args": [ - "--database=nfu_sale_order_batch", + "--database=nfu_", "--addons-path=${config:odoo.addons_path},${workspaceFolder}", "--limit-time-real=0", "--limit-time-cpu=0", - "--update=sale_order_batch,nfu_sale_order_packaging", - // "--update=", + // "--init=", + // "--update=", "--dev=xml" ] }, @@ -31,8 +31,8 @@ "--addons-path=${config:odoo.addons_path}", "--limit-time-real=0", "--limit-time-cpu=0", - "--init=sale_order_batch", - // "--update=", + // "--init=", + // "--update=", "--dev=xml" ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index ed0d60f..44d9e80 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,6 @@ "odoo.version": "16.0", "odoo.path": "../../versions/${config:odoo.version}/odoo", "odoo.addons_path": "${config:odoo.path}/addons", - "python.analysis.extraPaths": ["../../versions/16.0/odoo", "../../versions/16.0/OCA"] + "python.analysis.extraPaths": ["../../versions/16.0/odoo", "../../versions/16.0/OCA"], + "python.languageServer": "None" } From 7e0e9e58621736ee3605e02eef46e7452f0c646e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20G=C3=B6ttsch?= Date: Tue, 23 Jul 2024 21:25:28 +0200 Subject: [PATCH 07/10] [fix] string cosmetics and formating --- nfu_sale_order_packaging/models/sale_order_batch_product.py | 4 +--- .../views/sale_order_batch_product_views.xml | 2 +- sale_order_batch/models/sale_order_batch_product.py | 4 ++-- sale_order_batch/views/sale_order_batch_product_views.xml | 5 +++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/nfu_sale_order_packaging/models/sale_order_batch_product.py b/nfu_sale_order_packaging/models/sale_order_batch_product.py index c3f5535..f2c3cb8 100644 --- a/nfu_sale_order_packaging/models/sale_order_batch_product.py +++ b/nfu_sale_order_packaging/models/sale_order_batch_product.py @@ -10,9 +10,7 @@ class SaleOrderBatchProduct(models.Model): def _compute_open_packagin_qty(self): for product in self: open_packaging_qty = product.product_packaging_qty - ( - sum(product.sale_order_line_ids.mapped("product_uom_qty")) - % product.product_packaging_qty - % product.product_packaging_qty + sum(product.sale_order_line_ids.mapped("product_uom_qty")) % product.product_packaging_qty ) product.open_packaging_qty = ( 0 if open_packaging_qty == product.product_packaging_qty else open_packaging_qty diff --git a/nfu_sale_order_packaging/views/sale_order_batch_product_views.xml b/nfu_sale_order_packaging/views/sale_order_batch_product_views.xml index 564d876..0906e95 100644 --- a/nfu_sale_order_packaging/views/sale_order_batch_product_views.xml +++ b/nfu_sale_order_packaging/views/sale_order_batch_product_views.xml @@ -5,7 +5,7 @@ sale.order.batch.product - + - + + - + From 83ff3d9f671f8f0f6c3fc3bdd07168f661faa25f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20G=C3=B6ttsch?= Date: Tue, 23 Jul 2024 23:03:22 +0200 Subject: [PATCH 08/10] [imp] add batch invoicing, improve max_qty constraint --- nfu_sale_order_packaging/__manifest__.py | 2 +- .../models/sale_order_line.py | 11 ++++-- .../views/sale_order_batch_product_views.xml | 7 +++- .../views/sale_order_batch_views.xml | 7 +++- .../views/sale_order_views.xml | 4 +- sale_order_batch/models/sale_order_batch.py | 38 ++++++++++++++++--- .../views/sale_order_batch_product_views.xml | 1 + .../views/sale_order_batch_views.xml | 34 ++++++++++++++++- 8 files changed, 90 insertions(+), 14 deletions(-) diff --git a/nfu_sale_order_packaging/__manifest__.py b/nfu_sale_order_packaging/__manifest__.py index 81a61c0..9449913 100644 --- a/nfu_sale_order_packaging/__manifest__.py +++ b/nfu_sale_order_packaging/__manifest__.py @@ -3,7 +3,7 @@ "summary": "Add minimum and maximum order quantities to sale orders and use default packaging", "author": "BAKEUP", "website": "https://www.bakeup.org", - "category": "Stock", + "category": "Sale", "version": "16.0.0.0.1", "depends": ["sale", "sale_order_batch"], "data": [ diff --git a/nfu_sale_order_packaging/models/sale_order_line.py b/nfu_sale_order_packaging/models/sale_order_line.py index a0bd60b..7f6bd31 100644 --- a/nfu_sale_order_packaging/models/sale_order_line.py +++ b/nfu_sale_order_packaging/models/sale_order_line.py @@ -10,6 +10,11 @@ class SaleOrderLine(models.Model): @api.constrains("product_uom_qty", "product_uom_max_qty") def _check_product_uom_qty(self): - for record in self: - if record.product_uom_max_qty != 0 and record.product_uom_qty > record.product_uom_max_qty: - raise UserError(_("The quantity must be less than or equal to the maximum quantity.")) + for order_line in self: + if order_line.product_uom_max_qty != 0 and order_line.product_uom_qty > order_line.product_uom_max_qty: + raise UserError( + _( + f"{order_line.order_id.name},{order_line.product_id.name}:" + "The quantity must be less than or equal to the maximum quantity." + ) + ) diff --git a/nfu_sale_order_packaging/views/sale_order_batch_product_views.xml b/nfu_sale_order_packaging/views/sale_order_batch_product_views.xml index 0906e95..acac722 100644 --- a/nfu_sale_order_packaging/views/sale_order_batch_product_views.xml +++ b/nfu_sale_order_packaging/views/sale_order_batch_product_views.xml @@ -10,9 +10,14 @@ + + diff --git a/nfu_sale_order_packaging/views/sale_order_batch_views.xml b/nfu_sale_order_packaging/views/sale_order_batch_views.xml index aa7516b..ec519f8 100644 --- a/nfu_sale_order_packaging/views/sale_order_batch_views.xml +++ b/nfu_sale_order_packaging/views/sale_order_batch_views.xml @@ -7,9 +7,14 @@ + + diff --git a/nfu_sale_order_packaging/views/sale_order_views.xml b/nfu_sale_order_packaging/views/sale_order_views.xml index f0d2742..4922441 100644 --- a/nfu_sale_order_packaging/views/sale_order_views.xml +++ b/nfu_sale_order_packaging/views/sale_order_views.xml @@ -5,8 +5,10 @@ sale.order - + + + diff --git a/sale_order_batch/models/sale_order_batch.py b/sale_order_batch/models/sale_order_batch.py index 59afb0a..1bea44b 100644 --- a/sale_order_batch/models/sale_order_batch.py +++ b/sale_order_batch/models/sale_order_batch.py @@ -47,6 +47,8 @@ class SaleOrderBatch(models.Model): sale_order_ids = fields.One2many("sale.order", "batch_id") sale_order_count = fields.Integer(compute="_compute_sale_order_count") sale_order_line_ids = fields.Many2many("sale.order.line", compute="_compute_sale_order_line_ids", store=True) + invoice_ids = fields.Many2many("account.move", compute="_compute_invoice_ids") + invoice_count = fields.Integer(compute="_compute_invoice_ids") amount_total = fields.Float(compute="_compute_amount_total", string="Total") product_ids = fields.One2many("sale.order.batch.product", "batch_id") product_count = fields.Integer(compute="_compute_product_count") @@ -60,17 +62,24 @@ class SaleOrderBatch(models.Model): else: batch.validity_date = False - @api.depends("sale_order_ids") - def _compute_sale_order_count(self): - for batch in self: - batch.sale_order_count = len(batch.sale_order_ids) - @api.depends("sale_order_ids.order_line") def _compute_sale_order_line_ids(self): for batch in self: order_lines = self.env["sale.order.line"].search([("order_id", "in", batch.sale_order_ids.ids)]) batch.sale_order_line_ids = order_lines + @api.depends("sale_order_ids") + def _compute_sale_order_count(self): + for batch in self: + batch.sale_order_count = len(batch.sale_order_ids) + + @api.depends("sale_order_ids.invoice_ids") + def _compute_invoice_ids(self): + for batch in self: + invoices = batch.sale_order_ids.mapped("invoice_ids") + batch.invoice_ids = invoices + batch.invoice_count = len(invoices) + @api.depends("sale_order_ids.amount_total") def _compute_amount_total(self): for batch in self: @@ -113,6 +122,25 @@ class SaleOrderBatch(models.Model): result = {"type": "ir.actions.act_window_close"} return result + def action_view_invoice(self): + invoices = self.mapped("invoice_ids") + action = self.env["ir.actions.actions"]._for_xml_id("account.action_move_out_invoice_type") + if len(invoices) > 1: + action["domain"] = [("id", "in", invoices.ids)] + elif len(invoices) == 1: + form_view = [(self.env.ref("account.view_move_form").id, "form")] + if "views" in action: + action["views"] = form_view + [(state, view) for state, view in action["views"] if view != "form"] + else: + action["views"] = form_view + action["res_id"] = invoices.id + else: + action = {"type": "ir.actions.act_window_close"} + + context = {"default_move_type": "out_invoice"} + action["context"] = context + return action + def action_confirm(self): for batch in self: orders = batch.with_context(bypass_batch=True).sale_order_ids diff --git a/sale_order_batch/views/sale_order_batch_product_views.xml b/sale_order_batch/views/sale_order_batch_product_views.xml index a1661e6..b6e6a46 100644 --- a/sale_order_batch/views/sale_order_batch_product_views.xml +++ b/sale_order_batch/views/sale_order_batch_product_views.xml @@ -26,6 +26,7 @@ + diff --git a/sale_order_batch/views/sale_order_batch_views.xml b/sale_order_batch/views/sale_order_batch_views.xml index 9370be8..88147e8 100644 --- a/sale_order_batch/views/sale_order_batch_views.xml +++ b/sale_order_batch/views/sale_order_batch_views.xml @@ -29,6 +29,19 @@ type="object" attrs="{'invisible': [('state', '!=','open')]}" /> + +

@@ -76,7 +98,6 @@ @@ -84,6 +105,14 @@ + @@ -95,8 +124,9 @@ > + - + From 45a7c778640f3d5797c5d65c37a5763e4c1f0028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20G=C3=B6ttsch?= Date: Wed, 24 Jul 2024 08:35:30 +0200 Subject: [PATCH 09/10] [imp] add sale_order_batch_stock --- sale_order_batch_stock/README.rst | 65 +++ sale_order_batch_stock/__init__.py | 1 + sale_order_batch_stock/__manifest__.py | 12 + sale_order_batch_stock/models/__init__.py | 1 + .../models/sale_order_batch.py | 21 + .../readme/CONTRIBUTORS.rst | 1 + sale_order_batch_stock/readme/DESCRIPTION.rst | 1 + sale_order_batch_stock/readme/HISTORY.rst | 1 + .../static/description/index.html | 428 ++++++++++++++++++ .../views/sale_order_batch_views.xml | 22 + 10 files changed, 553 insertions(+) create mode 100644 sale_order_batch_stock/README.rst create mode 100644 sale_order_batch_stock/__init__.py create mode 100644 sale_order_batch_stock/__manifest__.py create mode 100644 sale_order_batch_stock/models/__init__.py create mode 100644 sale_order_batch_stock/models/sale_order_batch.py create mode 100644 sale_order_batch_stock/readme/CONTRIBUTORS.rst create mode 100644 sale_order_batch_stock/readme/DESCRIPTION.rst create mode 100644 sale_order_batch_stock/readme/HISTORY.rst create mode 100644 sale_order_batch_stock/static/description/index.html create mode 100644 sale_order_batch_stock/views/sale_order_batch_views.xml diff --git a/sale_order_batch_stock/README.rst b/sale_order_batch_stock/README.rst new file mode 100644 index 0000000..7e407bb --- /dev/null +++ b/sale_order_batch_stock/README.rst @@ -0,0 +1,65 @@ +============================== +Sale Order Batch Stock Binding +============================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:c32b4440b58e98f3bea5539d78dfa2916d64aebc757c140d78b67b2a2ce288da + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-bruecksen%2Fife_nfu-lightgray.png?logo=github + :target: https://github.com/bruecksen/ife_nfu/tree/16.0/sale_order_batch_stock + :alt: bruecksen/ife_nfu + +|badge1| |badge2| |badge3| + +This module adds Deliverys to Sale ORder Batch Views. + +**Table of contents** + +.. contents:: + :local: + +Changelog +========= + +:0.0.1: Initial module. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* BAKEUP + +Contributors +~~~~~~~~~~~~ + +* Niels Göttsch + +Maintainers +~~~~~~~~~~~ + +This module is part of the `bruecksen/ife_nfu `_ project on GitHub. + +You are welcome to contribute. diff --git a/sale_order_batch_stock/__init__.py b/sale_order_batch_stock/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/sale_order_batch_stock/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/sale_order_batch_stock/__manifest__.py b/sale_order_batch_stock/__manifest__.py new file mode 100644 index 0000000..950a05a --- /dev/null +++ b/sale_order_batch_stock/__manifest__.py @@ -0,0 +1,12 @@ +{ + "name": "Sale Order Batch Stock Binding", + "summary": "Sale Order Batch Stock Bindingh", + "author": "BAKEUP", + "website": "https://www.bakeup.org", + "category": "hidden", + "version": "16.0.0.0.1", + "depends": ["sale_order_batch", "sale_stock"], + "data": ["views/sale_order_batch_views.xml"], + "autoinstall": "True", + "license": "LGPL-3", +} diff --git a/sale_order_batch_stock/models/__init__.py b/sale_order_batch_stock/models/__init__.py new file mode 100644 index 0000000..b2dc7f4 --- /dev/null +++ b/sale_order_batch_stock/models/__init__.py @@ -0,0 +1 @@ +from . import sale_order_batch diff --git a/sale_order_batch_stock/models/sale_order_batch.py b/sale_order_batch_stock/models/sale_order_batch.py new file mode 100644 index 0000000..ff9a9e8 --- /dev/null +++ b/sale_order_batch_stock/models/sale_order_batch.py @@ -0,0 +1,21 @@ +from odoo import api, fields, models + + +STATES = [("open", "Open"), ("close", "Close")] + + +class SaleOrderBatch(models.Model): + _inherit = "sale.order.batch" + + picking_ids = fields.Many2many("stock.picking", compute="_compute_picking_ids", string="Transfers") + delivery_count = fields.Integer(string="Delivery Orders", compute="_compute_picking_ids") + + @api.depends("sale_order_ids.picking_ids") + def _compute_picking_ids(self): + for batch in self: + pickings = batch.sale_order_ids.mapped("picking_ids") + batch.picking_ids = pickings + batch.delivery_count = len(pickings) + + def action_view_delivery(self): + return self.env["sale.order"]._get_action_view_picking(self.picking_ids) diff --git a/sale_order_batch_stock/readme/CONTRIBUTORS.rst b/sale_order_batch_stock/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000..fda28e1 --- /dev/null +++ b/sale_order_batch_stock/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Niels Göttsch \ No newline at end of file diff --git a/sale_order_batch_stock/readme/DESCRIPTION.rst b/sale_order_batch_stock/readme/DESCRIPTION.rst new file mode 100644 index 0000000..2836d2a --- /dev/null +++ b/sale_order_batch_stock/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module adds Deliverys to Sale ORder Batch Views. diff --git a/sale_order_batch_stock/readme/HISTORY.rst b/sale_order_batch_stock/readme/HISTORY.rst new file mode 100644 index 0000000..e986fe7 --- /dev/null +++ b/sale_order_batch_stock/readme/HISTORY.rst @@ -0,0 +1 @@ +:0.0.1: Initial module. \ No newline at end of file diff --git a/sale_order_batch_stock/static/description/index.html b/sale_order_batch_stock/static/description/index.html new file mode 100644 index 0000000..515a69f --- /dev/null +++ b/sale_order_batch_stock/static/description/index.html @@ -0,0 +1,428 @@ + + + + + +Sale Order Batch Stock Binding + + + +
+

Sale Order Batch Stock Binding

+ + +

Beta License: LGPL-3 bruecksen/ife_nfu

+

This module adds Deliverys to Sale ORder Batch Views.

+

Table of contents

+ +
+

Changelog

+ +++ + + + +
0.0.1:Initial module.
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • BAKEUP
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is part of the bruecksen/ife_nfu project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + diff --git a/sale_order_batch_stock/views/sale_order_batch_views.xml b/sale_order_batch_stock/views/sale_order_batch_views.xml new file mode 100644 index 0000000..19a9e9e --- /dev/null +++ b/sale_order_batch_stock/views/sale_order_batch_views.xml @@ -0,0 +1,22 @@ + + + + sale.order.batch.form.stock + sale.order.batch + + + + + + + + From a9eca7d043e3cf021d0cab11e6fba1151989fc2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20G=C3=B6ttsch?= Date: Wed, 24 Jul 2024 08:40:58 +0200 Subject: [PATCH 10/10] [fix] add bakeup logos --- .vscode/launch.json | 4 ++-- sale_order_batch/static/description/icon.png | Bin 0 -> 12282 bytes .../static/description/icon.png | Bin 0 -> 12282 bytes 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 sale_order_batch/static/description/icon.png create mode 100644 sale_order_batch_stock/static/description/icon.png diff --git a/.vscode/launch.json b/.vscode/launch.json index f7805af..10199d7 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,11 +9,11 @@ "program": "${config:odoo.path}/odoo-bin", "console": "integratedTerminal", "args": [ - "--database=nfu_", + "--database=nfu_sale_order_batch_packaging", "--addons-path=${config:odoo.addons_path},${workspaceFolder}", "--limit-time-real=0", "--limit-time-cpu=0", - // "--init=", + "--update=sale_order_batch_stock", // "--update=", "--dev=xml" ] diff --git a/sale_order_batch/static/description/icon.png b/sale_order_batch/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..126771222c96d9acfa22f7f2d27f6f4b9ce7feb6 GIT binary patch literal 12282 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

W$<1~*|NZw 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 literal 0 HcmV?d00001 diff --git a/sale_order_batch_stock/static/description/icon.png b/sale_order_batch_stock/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..126771222c96d9acfa22f7f2d27f6f4b9ce7feb6 GIT binary patch literal 12282 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

W$<1~*|NZw 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 literal 0 HcmV?d00001