diff --git a/.hgtags b/.hgtags
index 2d2d5cec66..d6141febba 100644
--- a/.hgtags
+++ b/.hgtags
@@ -85,3 +85,1692 @@ d1e67fbb11774d0a7ca3bd5761cf4ea11dbaa4b8 stock-5.8.0
65d7e83be01e651274bc5eebd98deac8b4afceef stock-6.4.0
0000000000000000000000000000000000000000 6.6.0
f83c1c8c757c652767eb7651370f786f0a864e00 stock-6.6.0
+059c67523e52eda86c563a2414e2b6107b101a8d 1.2.0
+225b705164561d09d5fcae80b784da0fedd531fc 1.4.0
+185537801e5e1ed3b6a2f6719db0e999c0d805e1 1.6.0
+1e23789f77c3e731e73ddc789d8b9ce9f01efc70 1.8.0
+241ddb0a8f8ded2e160598d3efc2e2a00d64abc9 2.0.0
+739e08551f9b9d6e80619ad88d2a8e4e64e3c986 2.2.0
+0299558c412d8feb4db592e3f360fd4b0ecc52cc 2.4.0
+44e7cada1ccc7466f0c284505fd21c335cdb1f58 2.6.0
+f688494c52bc7de9316ae436d20441371a73b3ec 2.8.0
+931ee9f97e52351fc8c7dae24581168d1b3b8c18 3.0.0
+4870db0874d83c50955cbbca10af3ae5b26aae94 3.2.0
+154ea5fb86b75faffd363439f1d6e990d6936c68 3.4.0
+af2746cd736ea6c0d5deee681e9e6286513d2837 3.6.0
+cdc30282449ca7b4991228fde5f99d38673a4fd0 3.8.0
+2b15dc5cabb1156e41e49bcc64b55ae085f2e325 4.0.0
+f86b857b0aa3b56b09d5f574b3a4560b0b00502c 4.2.0
+b6f4180cc07450e9041db772ddfd0dca2f3134ef 4.4.0
+52b6e412dc583d0578df29abfb95cc3865cba4b2 4.6.0
+fc2aa3c75ba8fdb40273523e4fefb1777c4919f8 4.8.0
+bd5dc78969db8e574bef34ca69fa946e49c766ef 5.0.0
+9c0c444c4fda668a0ee25e016a67751a11b5e131 5.2.0
+639a8cb26974fca129c9d7bdae8bba88380c9efe 5.4.0
+dbced0dbb0ad20cf471c30cfafd2b0eee3cfe6d4 5.6.0
+ef5bc23acec6b070d72acd94a55539969f114699 5.8.0
+e5bea2a22f5042af86510ab283ef7f6a30276bfd 6.0.0
+6cf0c4d8f64ccaedf402800b446718200d74bbcb 6.2.0
+2406bcb73d0867cb64318cb3917d421ae50858a5 6.4.0
+e245f55d75a981d8b7968be54c9faeaa97c61e22 6.6.0
+0000000000000000000000000000000000000000 1.2.0
+059c67523e52eda86c563a2414e2b6107b101a8d stock_inventory_location-1.2.0
+0000000000000000000000000000000000000000 1.4.0
+225b705164561d09d5fcae80b784da0fedd531fc stock_inventory_location-1.4.0
+0000000000000000000000000000000000000000 1.6.0
+185537801e5e1ed3b6a2f6719db0e999c0d805e1 stock_inventory_location-1.6.0
+0000000000000000000000000000000000000000 1.8.0
+1e23789f77c3e731e73ddc789d8b9ce9f01efc70 stock_inventory_location-1.8.0
+0000000000000000000000000000000000000000 2.0.0
+241ddb0a8f8ded2e160598d3efc2e2a00d64abc9 stock_inventory_location-2.0.0
+0000000000000000000000000000000000000000 2.2.0
+739e08551f9b9d6e80619ad88d2a8e4e64e3c986 stock_inventory_location-2.2.0
+0000000000000000000000000000000000000000 2.4.0
+0299558c412d8feb4db592e3f360fd4b0ecc52cc stock_inventory_location-2.4.0
+0000000000000000000000000000000000000000 2.6.0
+44e7cada1ccc7466f0c284505fd21c335cdb1f58 stock_inventory_location-2.6.0
+0000000000000000000000000000000000000000 2.8.0
+f688494c52bc7de9316ae436d20441371a73b3ec stock_inventory_location-2.8.0
+0000000000000000000000000000000000000000 3.0.0
+931ee9f97e52351fc8c7dae24581168d1b3b8c18 stock_inventory_location-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+4870db0874d83c50955cbbca10af3ae5b26aae94 stock_inventory_location-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+154ea5fb86b75faffd363439f1d6e990d6936c68 stock_inventory_location-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+af2746cd736ea6c0d5deee681e9e6286513d2837 stock_inventory_location-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+cdc30282449ca7b4991228fde5f99d38673a4fd0 stock_inventory_location-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+2b15dc5cabb1156e41e49bcc64b55ae085f2e325 stock_inventory_location-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+f86b857b0aa3b56b09d5f574b3a4560b0b00502c stock_inventory_location-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+b6f4180cc07450e9041db772ddfd0dca2f3134ef stock_inventory_location-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+52b6e412dc583d0578df29abfb95cc3865cba4b2 stock_inventory_location-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+fc2aa3c75ba8fdb40273523e4fefb1777c4919f8 stock_inventory_location-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+bd5dc78969db8e574bef34ca69fa946e49c766ef stock_inventory_location-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+9c0c444c4fda668a0ee25e016a67751a11b5e131 stock_inventory_location-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+639a8cb26974fca129c9d7bdae8bba88380c9efe stock_inventory_location-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+dbced0dbb0ad20cf471c30cfafd2b0eee3cfe6d4 stock_inventory_location-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+ef5bc23acec6b070d72acd94a55539969f114699 stock_inventory_location-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+e5bea2a22f5042af86510ab283ef7f6a30276bfd stock_inventory_location-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+6cf0c4d8f64ccaedf402800b446718200d74bbcb stock_inventory_location-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+2406bcb73d0867cb64318cb3917d421ae50858a5 stock_inventory_location-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+e245f55d75a981d8b7968be54c9faeaa97c61e22 stock_inventory_location-6.6.0
+13bc032ce45aa856f7c929da56974ff13ff3b7f3 4.6.0
+c5757a882fa6b0f30a7bca1a2e232c59dbe8e997 4.8.0
+7712e9bf2ae5372165f1208c7fcf74caa77733b8 5.0.0
+9cadbedb76593e2b1046c483ff57a5cecb380a41 5.2.0
+061bb098401a21770b1f7d8491805fb2516d50b2 5.4.0
+35e0bc476e8e103ff133ab5797eed1d3979289b2 5.6.0
+a767051ad55af5437c1df4473f0d16251941bc79 5.8.0
+2657bcf38993689626952562bc1999027d0262cd 6.0.0
+3ebb517c91bc0b75b347d4e23fc63234aace7b22 6.2.0
+a71b982ae4381f840823a000af60c3c222c957f0 6.4.0
+26556d44c2fb84b55ef0c6ee513181c56e743148 6.6.0
+0000000000000000000000000000000000000000 4.6.0
+13bc032ce45aa856f7c929da56974ff13ff3b7f3 stock_location_move-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+c5757a882fa6b0f30a7bca1a2e232c59dbe8e997 stock_location_move-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+7712e9bf2ae5372165f1208c7fcf74caa77733b8 stock_location_move-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+9cadbedb76593e2b1046c483ff57a5cecb380a41 stock_location_move-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+061bb098401a21770b1f7d8491805fb2516d50b2 stock_location_move-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+35e0bc476e8e103ff133ab5797eed1d3979289b2 stock_location_move-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+a767051ad55af5437c1df4473f0d16251941bc79 stock_location_move-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+2657bcf38993689626952562bc1999027d0262cd stock_location_move-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+3ebb517c91bc0b75b347d4e23fc63234aace7b22 stock_location_move-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+a71b982ae4381f840823a000af60c3c222c957f0 stock_location_move-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+26556d44c2fb84b55ef0c6ee513181c56e743148 stock_location_move-6.6.0
+b23baaf1166b3f28f7aaa55b16d8f0b50e7121ed 1.2.0
+d9f7fda1212e61153ce87ef5a7ebba1aa906d9f2 1.4.0
+926f70090196ceefd74450f182a8a9b053282600 1.6.0
+9eada792e0e9eda93b8719d4ec92590f2ff3dacf 1.8.0
+8a47bba1738af17af3c6702cc29bd7a6e268dcfb 2.0.0
+c66ac42308b219dd773e9a4f2b76e344cf913cc8 2.2.0
+9a792408dcb3f2902a0c6da0c71db3ad1692dbd9 2.4.0
+5d56a013f279fc4b31e9a73a6e5b4bb8991e25ef 2.6.0
+d0821f9f197cab6cbeb260b6c230e301def3daea 2.8.0
+0a8b7366a62a97d33c7cdc1b6938fccd4ad4104e 3.0.0
+7e56cda8de6b9e0384104bd68e200f467af001bf 3.2.0
+9befac1e3076f141972816af2f6fe8782125df85 3.4.0
+db721dd4b8e93902f4e1173ff0d9f12f92260802 3.6.0
+5e18316f6f636a5474949d3bc5cb66c153e3da4b 3.8.0
+e052747c31f40fd68e13b0ec450c3ffc502e5e66 4.0.0
+13d25c22e30033991a1aa9233b7ecce233ebc6ea 4.2.0
+8eac3ea1d980cb34c5bda3255bc764ec079fe60f 4.4.0
+809b3a45222dbc93dc22785adbb184705b24502a 4.6.0
+ec2b60415d119b35cf61b75247abaf5bb67a70b1 4.8.0
+907c38d009f3853cddeb21db3e569e681e60a82f 5.0.0
+777c5d8d0ccec1c866450b98973009de6a5e38a5 5.2.0
+4abcc1fb1039f1cde5ba1277efc6edb713d427af 5.4.0
+93240765ffba8fb10f1fcc8699db8c9f5d827e36 5.6.0
+119bb6dcafeffabbe80a5b9fcb872071e0f3c784 5.8.0
+1a8e026150a29d49f552c112f9795b1f2ad035b6 6.0.0
+613034b9778b85d02ae1585a39e90039f13a3695 6.2.0
+47541d334066316ea3296e4eb2004da55c6b5e4f 6.4.0
+2ba005a00d90302b0bf759cf8528df1fca8bbaec 6.6.0
+0000000000000000000000000000000000000000 1.2.0
+b23baaf1166b3f28f7aaa55b16d8f0b50e7121ed stock_location_sequence-1.2.0
+0000000000000000000000000000000000000000 1.4.0
+d9f7fda1212e61153ce87ef5a7ebba1aa906d9f2 stock_location_sequence-1.4.0
+0000000000000000000000000000000000000000 1.6.0
+926f70090196ceefd74450f182a8a9b053282600 stock_location_sequence-1.6.0
+0000000000000000000000000000000000000000 1.8.0
+9eada792e0e9eda93b8719d4ec92590f2ff3dacf stock_location_sequence-1.8.0
+0000000000000000000000000000000000000000 2.0.0
+8a47bba1738af17af3c6702cc29bd7a6e268dcfb stock_location_sequence-2.0.0
+0000000000000000000000000000000000000000 2.2.0
+c66ac42308b219dd773e9a4f2b76e344cf913cc8 stock_location_sequence-2.2.0
+0000000000000000000000000000000000000000 2.4.0
+9a792408dcb3f2902a0c6da0c71db3ad1692dbd9 stock_location_sequence-2.4.0
+0000000000000000000000000000000000000000 2.6.0
+5d56a013f279fc4b31e9a73a6e5b4bb8991e25ef stock_location_sequence-2.6.0
+0000000000000000000000000000000000000000 2.8.0
+d0821f9f197cab6cbeb260b6c230e301def3daea stock_location_sequence-2.8.0
+0000000000000000000000000000000000000000 3.0.0
+0a8b7366a62a97d33c7cdc1b6938fccd4ad4104e stock_location_sequence-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+7e56cda8de6b9e0384104bd68e200f467af001bf stock_location_sequence-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+9befac1e3076f141972816af2f6fe8782125df85 stock_location_sequence-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+db721dd4b8e93902f4e1173ff0d9f12f92260802 stock_location_sequence-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+5e18316f6f636a5474949d3bc5cb66c153e3da4b stock_location_sequence-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+e052747c31f40fd68e13b0ec450c3ffc502e5e66 stock_location_sequence-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+13d25c22e30033991a1aa9233b7ecce233ebc6ea stock_location_sequence-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+8eac3ea1d980cb34c5bda3255bc764ec079fe60f stock_location_sequence-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+809b3a45222dbc93dc22785adbb184705b24502a stock_location_sequence-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+ec2b60415d119b35cf61b75247abaf5bb67a70b1 stock_location_sequence-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+907c38d009f3853cddeb21db3e569e681e60a82f stock_location_sequence-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+777c5d8d0ccec1c866450b98973009de6a5e38a5 stock_location_sequence-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+4abcc1fb1039f1cde5ba1277efc6edb713d427af stock_location_sequence-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+93240765ffba8fb10f1fcc8699db8c9f5d827e36 stock_location_sequence-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+119bb6dcafeffabbe80a5b9fcb872071e0f3c784 stock_location_sequence-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+1a8e026150a29d49f552c112f9795b1f2ad035b6 stock_location_sequence-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+613034b9778b85d02ae1585a39e90039f13a3695 stock_location_sequence-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+47541d334066316ea3296e4eb2004da55c6b5e4f stock_location_sequence-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+2ba005a00d90302b0bf759cf8528df1fca8bbaec stock_location_sequence-6.6.0
+f3daa4fc57a55e3f24f9430134a7db46b430d24a 2.4.0
+9bfebffac7ac532b86f50e1d93fc3b41d3921d77 2.6.0
+ac0210ea97cffd9aa37a5af53160243fbe0d7f56 2.8.0
+a358b629d083fbbe619614fcf3f26efaa21ff057 3.0.0
+2419d87bd5c29430664571dbd3376b556dc8ed83 3.2.0
+f72cb08228d56df2be724b462e5d9497dc700285 3.4.0
+8f644f057381856d5ab1834f34a981ff1b65fba3 3.6.0
+2918a530bb167f85c238e2dafe30ee6cf942ea70 3.8.0
+571f01b197f02ef5842c30e25e66515c9d1fa0c4 4.0.0
+e79c0e4b00b8455533c2992369e0ad78ce2fb4e0 4.2.0
+c5f89116f21e00e008b9dc515e82a291bc4a37a9 4.4.0
+e966c63314da859ecacd7e40356201e74d3bd715 4.6.0
+d6e8ca4264c50efb67ae4b0b4c2c7b6982612894 4.8.0
+a5722d02c1c5a5ccabf997d980a86bb6bd0160db 5.0.0
+0170b28fa1c9581bf0831a501469df19a3f7b302 5.2.0
+c77c42846d957aa443927c3eb3e0e489eabe3eeb 5.4.0
+4c6125ae5f16e2ded590b4a84c17ae9ab6f0e826 5.6.0
+6ccbea8c304a744066cefa9637aed2bb21ca5149 5.8.0
+2e05cf05ee95b78ad35fc10eeb51fc35a6b6bc9f 6.0.0
+188ebdc1fe97c6427635e6a6f5778c5000ba5938 6.2.0
+b5347defe5e8d03260599fd6e03002022b9a993c 6.4.0
+50613053f4b76964b7bcea9f7894fb77c068b50f 6.6.0
+0000000000000000000000000000000000000000 2.4.0
+f3daa4fc57a55e3f24f9430134a7db46b430d24a stock_lot-2.4.0
+0000000000000000000000000000000000000000 2.6.0
+9bfebffac7ac532b86f50e1d93fc3b41d3921d77 stock_lot-2.6.0
+0000000000000000000000000000000000000000 2.8.0
+ac0210ea97cffd9aa37a5af53160243fbe0d7f56 stock_lot-2.8.0
+0000000000000000000000000000000000000000 3.0.0
+a358b629d083fbbe619614fcf3f26efaa21ff057 stock_lot-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+2419d87bd5c29430664571dbd3376b556dc8ed83 stock_lot-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+f72cb08228d56df2be724b462e5d9497dc700285 stock_lot-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+8f644f057381856d5ab1834f34a981ff1b65fba3 stock_lot-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+2918a530bb167f85c238e2dafe30ee6cf942ea70 stock_lot-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+571f01b197f02ef5842c30e25e66515c9d1fa0c4 stock_lot-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+e79c0e4b00b8455533c2992369e0ad78ce2fb4e0 stock_lot-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+c5f89116f21e00e008b9dc515e82a291bc4a37a9 stock_lot-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+e966c63314da859ecacd7e40356201e74d3bd715 stock_lot-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+d6e8ca4264c50efb67ae4b0b4c2c7b6982612894 stock_lot-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+a5722d02c1c5a5ccabf997d980a86bb6bd0160db stock_lot-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+0170b28fa1c9581bf0831a501469df19a3f7b302 stock_lot-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+c77c42846d957aa443927c3eb3e0e489eabe3eeb stock_lot-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+4c6125ae5f16e2ded590b4a84c17ae9ab6f0e826 stock_lot-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+6ccbea8c304a744066cefa9637aed2bb21ca5149 stock_lot-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+2e05cf05ee95b78ad35fc10eeb51fc35a6b6bc9f stock_lot-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+188ebdc1fe97c6427635e6a6f5778c5000ba5938 stock_lot-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+b5347defe5e8d03260599fd6e03002022b9a993c stock_lot-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+50613053f4b76964b7bcea9f7894fb77c068b50f stock_lot-6.6.0
+f319ec0ab83850bfbc4dbf0c1e3f88923d4c6ba4 3.6.0
+086daa04833949d995472901fff5f58a5ad1ea7c 3.8.0
+f13eceee4f070ddd92d5bf3b4e37723989b25de5 4.0.0
+69a63fa91de5824e6c69c5283b7cc4a560faabde 4.2.0
+abbc7eac4114aeb9d1ec6aa43d7744d4df991431 4.4.0
+b8d5d4e6d18e736b29350b41559f86e1b552c496 4.6.0
+fea52fe8ed7b3233a42ceb4b4185d7db3adf359f 4.8.0
+7e17d7d28b28cf0e6be49af141ba094b802f9b0d 5.0.0
+9d45f2cfdb3983e8fe676177066f8d37f5a8d18d 5.2.0
+19f381cd840ef2196eddcbc954937b3f2b3db661 5.4.0
+d977882bd686aabe9cf7a56b08710358fb8d9960 5.6.0
+78740da434731b98192332919c0cad73f0553da6 5.8.0
+226bd337f659e121a6be8f9c01e5341c1d366a94 6.0.0
+771f2086b196fc5756e7bfcaf52365abd00d10e9 6.2.0
+af1f96f38c986ef0c8b960d83c9725d3c525c709 6.4.0
+2a4f3a2eeb07431a35a32d69ccec9d4d3f5014dc 6.6.0
+0000000000000000000000000000000000000000 3.6.0
+f319ec0ab83850bfbc4dbf0c1e3f88923d4c6ba4 stock_lot_sled-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+086daa04833949d995472901fff5f58a5ad1ea7c stock_lot_sled-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+f13eceee4f070ddd92d5bf3b4e37723989b25de5 stock_lot_sled-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+69a63fa91de5824e6c69c5283b7cc4a560faabde stock_lot_sled-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+abbc7eac4114aeb9d1ec6aa43d7744d4df991431 stock_lot_sled-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+b8d5d4e6d18e736b29350b41559f86e1b552c496 stock_lot_sled-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+fea52fe8ed7b3233a42ceb4b4185d7db3adf359f stock_lot_sled-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+7e17d7d28b28cf0e6be49af141ba094b802f9b0d stock_lot_sled-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+9d45f2cfdb3983e8fe676177066f8d37f5a8d18d stock_lot_sled-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+19f381cd840ef2196eddcbc954937b3f2b3db661 stock_lot_sled-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+d977882bd686aabe9cf7a56b08710358fb8d9960 stock_lot_sled-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+78740da434731b98192332919c0cad73f0553da6 stock_lot_sled-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+226bd337f659e121a6be8f9c01e5341c1d366a94 stock_lot_sled-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+771f2086b196fc5756e7bfcaf52365abd00d10e9 stock_lot_sled-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+af1f96f38c986ef0c8b960d83c9725d3c525c709 stock_lot_sled-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+2a4f3a2eeb07431a35a32d69ccec9d4d3f5014dc stock_lot_sled-6.6.0
+7841e7ccbb5af34441c92e9b24caae751ca71194 5.0.0
+accb9a9e2eecea2c07521b46f81d22bbb13c6efc 5.2.0
+52a0d3ff69fa733416ddb698e73c99a17309ffe1 5.4.0
+fb5d9bead5daa2058a5d59f3ef18de584202b4d6 5.6.0
+703868576e2ab157fe5aadae42c7e6931098aa40 5.8.0
+cc2dd321d99fe14fe9251051eee46a6903c57bc4 6.0.0
+1b88c1efab8e6d8c128b0eed0395603ccb2d1ffd 6.2.0
+e5d8ffaf91c7afd4f809b0bc441827edc8673dda 6.4.0
+3b990739f8071bb9bcc46bfb5f45a2f71532f296 6.6.0
+0000000000000000000000000000000000000000 5.0.0
+7841e7ccbb5af34441c92e9b24caae751ca71194 stock_lot_unit-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+accb9a9e2eecea2c07521b46f81d22bbb13c6efc stock_lot_unit-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+52a0d3ff69fa733416ddb698e73c99a17309ffe1 stock_lot_unit-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+fb5d9bead5daa2058a5d59f3ef18de584202b4d6 stock_lot_unit-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+703868576e2ab157fe5aadae42c7e6931098aa40 stock_lot_unit-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+cc2dd321d99fe14fe9251051eee46a6903c57bc4 stock_lot_unit-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+1b88c1efab8e6d8c128b0eed0395603ccb2d1ffd stock_lot_unit-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+e5d8ffaf91c7afd4f809b0bc441827edc8673dda stock_lot_unit-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+3b990739f8071bb9bcc46bfb5f45a2f71532f296 stock_lot_unit-6.6.0
+2d95440ef29e4e6ae8bf7c513b4cced6038974ad 3.2.0
+5886452ff995b50071f07e05f519b2e4bb0526c9 3.4.0
+ed428643d547655cf08fd33ac6700bedc75308c6 3.6.0
+600f0b784df713a34b9c770622bc8dfd8a2a8c78 3.8.0
+e46734b4ac890bb0bf34bf08e261a6390fb7c3a8 4.0.0
+abf3fe276ee219d027e78dc72ec570add038899b 4.2.0
+e3764726bbbe93305d2e3e8bb20746cd0b33ae4f 4.4.0
+876b678e056f2ba5ae6108b10182c8e3b72184d1 4.6.0
+85793ff5a50a432be0fb45012478972b4c60e056 4.8.0
+6a0a6190312f634e8b64b6997fb1b37129532fbe 5.0.0
+d761efb2ac196534d0ff715146bd9b727c20bd40 5.2.0
+25ebab75a5457e2e00ed334edae56d5f5991a603 5.4.0
+3d96d408e7cb3cc3552ca3b99356990b889f78f6 5.6.0
+28f4106d4fc02d7c6d7f8735a58422031e3e3e1a 5.8.0
+a4cd8b29bbafd25dcf991704353b57b10e383f59 6.0.0
+f3109538cd603d85a10e5070ce8a1bfd92416dfe 6.2.0
+260a52bf21527f2e746e08ae3e2eb5d86551fdf2 6.4.0
+b812bca2a752860635219290eca696b83042e406 6.6.0
+0000000000000000000000000000000000000000 3.2.0
+2d95440ef29e4e6ae8bf7c513b4cced6038974ad stock_package-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+5886452ff995b50071f07e05f519b2e4bb0526c9 stock_package-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+ed428643d547655cf08fd33ac6700bedc75308c6 stock_package-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+600f0b784df713a34b9c770622bc8dfd8a2a8c78 stock_package-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+e46734b4ac890bb0bf34bf08e261a6390fb7c3a8 stock_package-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+abf3fe276ee219d027e78dc72ec570add038899b stock_package-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+e3764726bbbe93305d2e3e8bb20746cd0b33ae4f stock_package-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+876b678e056f2ba5ae6108b10182c8e3b72184d1 stock_package-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+85793ff5a50a432be0fb45012478972b4c60e056 stock_package-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+6a0a6190312f634e8b64b6997fb1b37129532fbe stock_package-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+d761efb2ac196534d0ff715146bd9b727c20bd40 stock_package-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+25ebab75a5457e2e00ed334edae56d5f5991a603 stock_package-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+3d96d408e7cb3cc3552ca3b99356990b889f78f6 stock_package-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+28f4106d4fc02d7c6d7f8735a58422031e3e3e1a stock_package-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+a4cd8b29bbafd25dcf991704353b57b10e383f59 stock_package-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+f3109538cd603d85a10e5070ce8a1bfd92416dfe stock_package-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+260a52bf21527f2e746e08ae3e2eb5d86551fdf2 stock_package-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+b812bca2a752860635219290eca696b83042e406 stock_package-6.6.0
+5352520b9e2d793f180c7338973c93eb2756c11a 4.2.0
+48eda81a2c3e4697d12b3ecd43d20cdffdf7f95d 4.4.0
+72b19785f7aefa42c43dbf7430b70393abfafdac 4.6.0
+a3fda5824dc2e831806bb3e54c4b554e28707d66 4.8.0
+c91e82164a66fa45b1e5f5c18f4eecb9666ff9f9 5.0.0
+1d75d725c02de30176404a116395f5cea1a8b15d 5.2.0
+f774a1f78ac021fd0dbe822bde61f5300f1ee672 5.4.0
+e9c1c8ee8d12182e14e0b7fda103035e43d957ef 5.6.0
+879357ee52cac15348178e8cba439074c7fcc206 5.8.0
+ba57075f760026b8388fb77bd0cc053601bd04b0 6.0.0
+6216cdc125f78a1071e72bb49cc7fcdff2b82667 6.2.0
+053fff25d83a0378a37b43591d864becdb8dd217 6.4.0
+1ec0ff090be4cead1d05df473cf8fbdfe0810c88 6.6.0
+0000000000000000000000000000000000000000 4.2.0
+5352520b9e2d793f180c7338973c93eb2756c11a stock_package_shipping_dpd-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+48eda81a2c3e4697d12b3ecd43d20cdffdf7f95d stock_package_shipping_dpd-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+72b19785f7aefa42c43dbf7430b70393abfafdac stock_package_shipping_dpd-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+a3fda5824dc2e831806bb3e54c4b554e28707d66 stock_package_shipping_dpd-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+c91e82164a66fa45b1e5f5c18f4eecb9666ff9f9 stock_package_shipping_dpd-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+1d75d725c02de30176404a116395f5cea1a8b15d stock_package_shipping_dpd-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+f774a1f78ac021fd0dbe822bde61f5300f1ee672 stock_package_shipping_dpd-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+e9c1c8ee8d12182e14e0b7fda103035e43d957ef stock_package_shipping_dpd-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+879357ee52cac15348178e8cba439074c7fcc206 stock_package_shipping_dpd-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+ba57075f760026b8388fb77bd0cc053601bd04b0 stock_package_shipping_dpd-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+6216cdc125f78a1071e72bb49cc7fcdff2b82667 stock_package_shipping_dpd-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+053fff25d83a0378a37b43591d864becdb8dd217 stock_package_shipping_dpd-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+1ec0ff090be4cead1d05df473cf8fbdfe0810c88 stock_package_shipping_dpd-6.6.0
+6d6ce7193b8fe468b131732a63d49ad51282feb4 4.2.0
+c92db1ac0cb7f23ec59451a1559ae587489e51cf 4.4.0
+896bda88b3e4e06011cc8274248a747c98ed5d8a 4.6.0
+12732a7de25ada586b597f5ceb95a61aca85c982 4.8.0
+d84a549ca4ce55c8b6f2c55e7b387111fe5d31f5 5.0.0
+dfa6486ca4ca8a505a1103a1966f252bfb76b0d5 5.2.0
+fc827a8182eeabea27b4107630814f58615a5093 5.4.0
+1e8a3c6dcb32eebb16c0135a83c6d24a178809a0 5.6.0
+4afae51825024fa5bdda4845018c68076e37f985 5.8.0
+4d757048f5cf112af97613ed3cd8c1d9747d5932 6.0.0
+0f981b2c2095bb4284ed6e1abe9e5f076e44bc65 6.2.0
+656bbe82f32db7cc41ba407bb46eb8ef4d78b72d 6.4.0
+81a891f156685cf5afe526044217c806990d462b 6.6.0
+0000000000000000000000000000000000000000 4.2.0
+6d6ce7193b8fe468b131732a63d49ad51282feb4 stock_package_shipping-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+c92db1ac0cb7f23ec59451a1559ae587489e51cf stock_package_shipping-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+896bda88b3e4e06011cc8274248a747c98ed5d8a stock_package_shipping-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+12732a7de25ada586b597f5ceb95a61aca85c982 stock_package_shipping-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+d84a549ca4ce55c8b6f2c55e7b387111fe5d31f5 stock_package_shipping-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+dfa6486ca4ca8a505a1103a1966f252bfb76b0d5 stock_package_shipping-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+fc827a8182eeabea27b4107630814f58615a5093 stock_package_shipping-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+1e8a3c6dcb32eebb16c0135a83c6d24a178809a0 stock_package_shipping-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+4afae51825024fa5bdda4845018c68076e37f985 stock_package_shipping-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+4d757048f5cf112af97613ed3cd8c1d9747d5932 stock_package_shipping-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+0f981b2c2095bb4284ed6e1abe9e5f076e44bc65 stock_package_shipping-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+656bbe82f32db7cc41ba407bb46eb8ef4d78b72d stock_package_shipping-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+81a891f156685cf5afe526044217c806990d462b stock_package_shipping-6.6.0
+efe8ad65ecc999176a779e8a5b9506916223081e 6.2.0
+e70bee6490857d56f447491144ef6d6e61bf229a 6.4.0
+dd62e5e8f5838b5653e649ec07968ee07c972f71 6.6.0
+0000000000000000000000000000000000000000 6.2.0
+efe8ad65ecc999176a779e8a5b9506916223081e stock_package_shipping_mygls-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+e70bee6490857d56f447491144ef6d6e61bf229a stock_package_shipping_mygls-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+dd62e5e8f5838b5653e649ec07968ee07c972f71 stock_package_shipping_mygls-6.6.0
+7bdde48affeaf205d5698d453b5ae136c8dcf69a 6.2.0
+85f567bf416a2e725f88c9e68f11cec2fb97ba53 6.4.0
+086fa4d627bd13cea36e72e923ae18e7b387fe12 6.6.0
+0000000000000000000000000000000000000000 6.2.0
+7bdde48affeaf205d5698d453b5ae136c8dcf69a stock_package_shipping_sendcloud-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+85f567bf416a2e725f88c9e68f11cec2fb97ba53 stock_package_shipping_sendcloud-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+086fa4d627bd13cea36e72e923ae18e7b387fe12 stock_package_shipping_sendcloud-6.6.0
+14873b27f47664b486aa92a3318081ee86d5cca7 4.2.0
+cd53d5490f327e9e13479e7d1540b47c111f4a23 4.4.0
+ca475eeb8c9c520c70346d799d444bb7225bd55b 4.6.0
+4437ebda9bc7470b4b98ee42370d12a6f942b1c3 4.8.0
+3e4c032cdadea2e021de270022e212eadb23c9d8 5.0.0
+4cde26523853d124058cc72a0bacc483c388c750 5.2.0
+84fdbd3bf2bccebc09b4216e01d9b93193d14daf 5.4.0
+7e0f69141e15402340c207ebefbb2e43083cf1ad 5.6.0
+c338db57b720be61b239b5f39f0080d062ee131e 5.8.0
+7c788a324e4e275dda49e425ab502fe792cc5bec 6.0.0
+d2df4ecc1213be8c5ff84508ec7c72fa2a38f457 6.2.0
+92b93590f3c5e0fc8520d61181aeb2bfc85af729 6.4.0
+954087b1fe9ed0441b5ac0dbaae3700754422b02 6.6.0
+0000000000000000000000000000000000000000 4.2.0
+14873b27f47664b486aa92a3318081ee86d5cca7 stock_package_shipping_ups-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+cd53d5490f327e9e13479e7d1540b47c111f4a23 stock_package_shipping_ups-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+ca475eeb8c9c520c70346d799d444bb7225bd55b stock_package_shipping_ups-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+4437ebda9bc7470b4b98ee42370d12a6f942b1c3 stock_package_shipping_ups-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+3e4c032cdadea2e021de270022e212eadb23c9d8 stock_package_shipping_ups-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+4cde26523853d124058cc72a0bacc483c388c750 stock_package_shipping_ups-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+84fdbd3bf2bccebc09b4216e01d9b93193d14daf stock_package_shipping_ups-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+7e0f69141e15402340c207ebefbb2e43083cf1ad stock_package_shipping_ups-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+c338db57b720be61b239b5f39f0080d062ee131e stock_package_shipping_ups-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+7c788a324e4e275dda49e425ab502fe792cc5bec stock_package_shipping_ups-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+d2df4ecc1213be8c5ff84508ec7c72fa2a38f457 stock_package_shipping_ups-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+92b93590f3c5e0fc8520d61181aeb2bfc85af729 stock_package_shipping_ups-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+954087b1fe9ed0441b5ac0dbaae3700754422b02 stock_package_shipping_ups-6.6.0
+2ea983f6240bd88f6b9abf2e4b7b857ce4bdf264 1.2.0
+ec24bd0ab6daa217e29753b68f9ae242f80062b7 1.4.0
+c560e70b18afce2d136cfbcc9f1ebf5756761882 1.6.0
+ab792b3468742c3a1f777165f8bdde4ebc96c1fd 1.8.0
+67d1514d90ff98a12865eaa025269914b15082b8 2.0.0
+53b4739836b0d10620038cce567d4d935f1a1363 2.2.0
+1922c46f7101f9397889c59c908bdd1e4489f70b 2.4.0
+b8e5502b8bd42741c92695a6540fade63bffbd43 2.6.0
+010a427751135ecb84ce3d7c13791ecf37edde23 2.8.0
+0dc520d1c9eeb9e242d5fb61fe2263ac28f5903f 3.0.0
+40cd13193206cc64a30dd7776fa954af1bceded9 3.2.0
+85c6a4a6a1d99d5c99228952115f1a57289856ba 3.4.0
+d2f9dbbcab386708468c523572888c7649e32851 3.6.0
+c540f2937c11c85591041fc8c2c4afd0ff53228f 3.8.0
+e8b3d84c1317eacc7b6b44b53b8ae70859b7977b 4.0.0
+b5442c0b44dc60bb6486bc308636bd37d1f5ff88 4.2.0
+ef4be934e362ed9336b2242ef1f3b799e724dfea 4.4.0
+3d5ef5ae2d89470391e2f59ae298312c670a93fa 4.6.0
+a41145e1e25e6348642c3fef1fb37d68142afc57 4.8.0
+1ea4345152b56228edf41029cf33318c5090cf29 5.0.0
+c10048ef95077f6c48ec1a3dd2cda9b29a55d9ef 5.2.0
+361b17eb46d869242083f3b2d269bc584bc17579 5.4.0
+a02f09f5837245a86c17ca480d069694b85d8214 5.6.0
+dfea61949c69f6013213cc92528fcfbc62e0a0f6 5.8.0
+25101e7ec2d7d8322005ae0e70f3d78256223ebe 6.0.0
+18a35510777ea296aff2bdc46fa4fc156fb6a2b6 6.2.0
+8f8e0041380e8a6dded2149eeb2f83993e98cb4f 6.4.0
+11e9e50a83519832fc3a654c6a2893a47af1c852 6.6.0
+0000000000000000000000000000000000000000 1.2.0
+2ea983f6240bd88f6b9abf2e4b7b857ce4bdf264 stock_product_location-1.2.0
+0000000000000000000000000000000000000000 1.4.0
+ec24bd0ab6daa217e29753b68f9ae242f80062b7 stock_product_location-1.4.0
+0000000000000000000000000000000000000000 1.6.0
+c560e70b18afce2d136cfbcc9f1ebf5756761882 stock_product_location-1.6.0
+0000000000000000000000000000000000000000 1.8.0
+ab792b3468742c3a1f777165f8bdde4ebc96c1fd stock_product_location-1.8.0
+0000000000000000000000000000000000000000 2.0.0
+67d1514d90ff98a12865eaa025269914b15082b8 stock_product_location-2.0.0
+0000000000000000000000000000000000000000 2.2.0
+53b4739836b0d10620038cce567d4d935f1a1363 stock_product_location-2.2.0
+0000000000000000000000000000000000000000 2.4.0
+1922c46f7101f9397889c59c908bdd1e4489f70b stock_product_location-2.4.0
+0000000000000000000000000000000000000000 2.6.0
+b8e5502b8bd42741c92695a6540fade63bffbd43 stock_product_location-2.6.0
+0000000000000000000000000000000000000000 2.8.0
+010a427751135ecb84ce3d7c13791ecf37edde23 stock_product_location-2.8.0
+0000000000000000000000000000000000000000 3.0.0
+0dc520d1c9eeb9e242d5fb61fe2263ac28f5903f stock_product_location-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+40cd13193206cc64a30dd7776fa954af1bceded9 stock_product_location-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+85c6a4a6a1d99d5c99228952115f1a57289856ba stock_product_location-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+d2f9dbbcab386708468c523572888c7649e32851 stock_product_location-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+c540f2937c11c85591041fc8c2c4afd0ff53228f stock_product_location-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+e8b3d84c1317eacc7b6b44b53b8ae70859b7977b stock_product_location-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+b5442c0b44dc60bb6486bc308636bd37d1f5ff88 stock_product_location-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+ef4be934e362ed9336b2242ef1f3b799e724dfea stock_product_location-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+3d5ef5ae2d89470391e2f59ae298312c670a93fa stock_product_location-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+a41145e1e25e6348642c3fef1fb37d68142afc57 stock_product_location-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+1ea4345152b56228edf41029cf33318c5090cf29 stock_product_location-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+c10048ef95077f6c48ec1a3dd2cda9b29a55d9ef stock_product_location-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+361b17eb46d869242083f3b2d269bc584bc17579 stock_product_location-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+a02f09f5837245a86c17ca480d069694b85d8214 stock_product_location-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+dfea61949c69f6013213cc92528fcfbc62e0a0f6 stock_product_location-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+25101e7ec2d7d8322005ae0e70f3d78256223ebe stock_product_location-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+18a35510777ea296aff2bdc46fa4fc156fb6a2b6 stock_product_location-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+8f8e0041380e8a6dded2149eeb2f83993e98cb4f stock_product_location-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+11e9e50a83519832fc3a654c6a2893a47af1c852 stock_product_location-6.6.0
+790271308b23a4856ade0be330ee59b5d69e7e75 6.0.0
+729e05a801e119103c3087b3f8708632d0121ee2 6.2.0
+300d3e729f2ce6c918ea534784d82917315a2e82 6.4.0
+c9f273114e8b76b0154115cb01f9a0345109cf84 6.6.0
+0000000000000000000000000000000000000000 6.0.0
+790271308b23a4856ade0be330ee59b5d69e7e75 stock_quantity_early_planning-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+729e05a801e119103c3087b3f8708632d0121ee2 stock_quantity_early_planning-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+300d3e729f2ce6c918ea534784d82917315a2e82 stock_quantity_early_planning-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+c9f273114e8b76b0154115cb01f9a0345109cf84 stock_quantity_early_planning-6.6.0
+8c7dc4a68eb44600a2e57f380b7fb39e7d4c9bd7 6.0.0
+180fa9e24693b07498ca2994729aa234e5f2f230 6.2.0
+12dbb1ede87b8d90716c7bd3d93116a5ef06cbf1 6.4.0
+693c2fbb45dee895662a6c24d8ebe55e9ca5bb53 6.6.0
+0000000000000000000000000000000000000000 6.0.0
+8c7dc4a68eb44600a2e57f380b7fb39e7d4c9bd7 stock_quantity_issue-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+180fa9e24693b07498ca2994729aa234e5f2f230 stock_quantity_issue-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+12dbb1ede87b8d90716c7bd3d93116a5ef06cbf1 stock_quantity_issue-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+693c2fbb45dee895662a6c24d8ebe55e9ca5bb53 stock_quantity_issue-6.6.0
+5e63bae17297495d2b63041be081e6bb8a69be2e 5.4.0
+83b28ed660ea0a02ba4cbaea22f495f2b3038615 5.6.0
+d7e3a25d15aa72096b29d985483e3caeb1fc4a43 5.8.0
+e55605b40ed71ec25e3079bb9c8b473bf879af58 6.0.0
+f3fd1dcb37f9d934da6f6bb0c31770409a93265f 6.2.0
+b7fb7dc89a758cc91d55f523db7513c6365b7af2 6.4.0
+1ab9ff3f2173cca3d03571d4b090e1e9fa085632 6.6.0
+0000000000000000000000000000000000000000 5.4.0
+5e63bae17297495d2b63041be081e6bb8a69be2e stock_secondary_unit-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+83b28ed660ea0a02ba4cbaea22f495f2b3038615 stock_secondary_unit-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+d7e3a25d15aa72096b29d985483e3caeb1fc4a43 stock_secondary_unit-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+e55605b40ed71ec25e3079bb9c8b473bf879af58 stock_secondary_unit-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+f3fd1dcb37f9d934da6f6bb0c31770409a93265f stock_secondary_unit-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+b7fb7dc89a758cc91d55f523db7513c6365b7af2 stock_secondary_unit-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+1ab9ff3f2173cca3d03571d4b090e1e9fa085632 stock_secondary_unit-6.6.0
+e2d7e4135cc43091843e096a227cb69ded3b425a 6.0.0
+e86dc3d9aaf74d02f4d76b7b39be6cccc45df90a 6.2.0
+e669817bef263fe9cfc7b9d065f2fd6464c33825 6.4.0
+3c296d4df695e3b1b0e8a13d54e767db5b0b6aec 6.6.0
+0000000000000000000000000000000000000000 6.0.0
+e2d7e4135cc43091843e096a227cb69ded3b425a stock_shipment_cost-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+e86dc3d9aaf74d02f4d76b7b39be6cccc45df90a stock_shipment_cost-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+e669817bef263fe9cfc7b9d065f2fd6464c33825 stock_shipment_cost-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+3c296d4df695e3b1b0e8a13d54e767db5b0b6aec stock_shipment_cost-6.6.0
+738617ef9100cb2bca45596cdaa48c75ad3cfd5e 6.4.0
+ffcd53cff4353e6d17547b5f7d31e2ef2c5ea1b2 6.6.0
+0000000000000000000000000000000000000000 6.4.0
+738617ef9100cb2bca45596cdaa48c75ad3cfd5e stock_shipment_cost_weight-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+ffcd53cff4353e6d17547b5f7d31e2ef2c5ea1b2 stock_shipment_cost_weight-6.6.0
+b11be33a256e6e18c5e478831f2eecdb6cc55b56 4.4.0
+a8fa5ceb9134b53a902c8b860e8d910ab36267bd 4.6.0
+55fcd1727648050cba394388bb31ce0a70b74371 4.8.0
+568b1d3a4957cc66a2023eb3853555fd8b2b313a 5.0.0
+df952bd9a9312169cce9a3559a6808fd15ce729f 5.2.0
+135db8a22874fd324ea9ca94b2f47c5f9d1671f7 5.4.0
+8e1fe403bf2728fcd47d00652c985dbb86b4840c 5.6.0
+5900e412e77ddf587a4ce0d69cde3a3a1e4c5fa3 5.8.0
+5fa8a7ad24a9d9c5726f08a174c22696480bb3c9 6.0.0
+63c1d22cdd2cb1a4ebc8c3b1e71d3b18487060d2 6.2.0
+d823ffc0ccd4eb62d5621560582b03253fddb346 6.4.0
+a4431f200ae5d4e89fb90795c88258261156220d 6.6.0
+0000000000000000000000000000000000000000 4.4.0
+b11be33a256e6e18c5e478831f2eecdb6cc55b56 stock_shipment_measurements-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+a8fa5ceb9134b53a902c8b860e8d910ab36267bd stock_shipment_measurements-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+55fcd1727648050cba394388bb31ce0a70b74371 stock_shipment_measurements-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+568b1d3a4957cc66a2023eb3853555fd8b2b313a stock_shipment_measurements-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+df952bd9a9312169cce9a3559a6808fd15ce729f stock_shipment_measurements-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+135db8a22874fd324ea9ca94b2f47c5f9d1671f7 stock_shipment_measurements-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+8e1fe403bf2728fcd47d00652c985dbb86b4840c stock_shipment_measurements-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+5900e412e77ddf587a4ce0d69cde3a3a1e4c5fa3 stock_shipment_measurements-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+5fa8a7ad24a9d9c5726f08a174c22696480bb3c9 stock_shipment_measurements-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+63c1d22cdd2cb1a4ebc8c3b1e71d3b18487060d2 stock_shipment_measurements-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+d823ffc0ccd4eb62d5621560582b03253fddb346 stock_shipment_measurements-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+a4431f200ae5d4e89fb90795c88258261156220d stock_shipment_measurements-6.6.0
+28368573eba198c3524a0ef44c5d1318a71a25b6 2.4.0
+04196701d026d86eb57f91c6e38cddecf257d63f 2.6.0
+099647a527ee5b315f03850b900f656bd10d759f 2.8.0
+06bc610a6f9a26c456050fd61c273bd012a21f04 3.0.0
+e793ef3ca432a0e409aa49bc846bd2c572f3a5ee 3.2.0
+99999433d0e31e2b6f1eb2f589844e835d7b2953 3.4.0
+4c27a1322efba12ae02f1299e7989460ffe8af09 3.6.0
+cca693a2c563e30e5f10fefeca30c49101eb3495 3.8.0
+d961a4a36143eae4ff23dc2c8f7b49c83a8e6b9a 4.0.0
+10eb3100612be23bcac20f5c1036e58aaef76ed7 4.2.0
+d73f07a6109ae14f711d9ac9efe316a4595d3ffa 4.4.0
+893b0270a268be94790a68facfb745cc188d7a93 4.6.0
+eef7e68926b3f9c34ae5dc12bcd0ec6884918c09 4.8.0
+fd97dee9a2f6c5fc4c3ddd7298fdcf4c917ef5d9 5.0.0
+c07759c9b8d3b7733620789a050e7b6de418cf99 5.2.0
+160bbe8565f066ff2e7565fd8a9aceec2c3a0bed 5.4.0
+51f597bea6844c61a7dd658329a0e55e011e5327 5.6.0
+f13147d0020a5a42a7420db6678d2472ccf79bd3 5.8.0
+69d98ca60d7117c6ea722ea3d69fb7896859614b 6.0.0
+5cda0f5b743d0d42a58187e5d38585e5e4ec7f1d 6.2.0
+3e649b6f6f2a16621caa05565ffcc8934bcb308e 6.4.0
+ca9aef457838d9bae9cddc270e83239c3d08dfde 6.6.0
+0000000000000000000000000000000000000000 2.4.0
+28368573eba198c3524a0ef44c5d1318a71a25b6 stock_split-2.4.0
+0000000000000000000000000000000000000000 2.6.0
+04196701d026d86eb57f91c6e38cddecf257d63f stock_split-2.6.0
+0000000000000000000000000000000000000000 2.8.0
+099647a527ee5b315f03850b900f656bd10d759f stock_split-2.8.0
+0000000000000000000000000000000000000000 3.0.0
+06bc610a6f9a26c456050fd61c273bd012a21f04 stock_split-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+e793ef3ca432a0e409aa49bc846bd2c572f3a5ee stock_split-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+99999433d0e31e2b6f1eb2f589844e835d7b2953 stock_split-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+4c27a1322efba12ae02f1299e7989460ffe8af09 stock_split-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+cca693a2c563e30e5f10fefeca30c49101eb3495 stock_split-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+d961a4a36143eae4ff23dc2c8f7b49c83a8e6b9a stock_split-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+10eb3100612be23bcac20f5c1036e58aaef76ed7 stock_split-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+d73f07a6109ae14f711d9ac9efe316a4595d3ffa stock_split-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+893b0270a268be94790a68facfb745cc188d7a93 stock_split-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+eef7e68926b3f9c34ae5dc12bcd0ec6884918c09 stock_split-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+fd97dee9a2f6c5fc4c3ddd7298fdcf4c917ef5d9 stock_split-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+c07759c9b8d3b7733620789a050e7b6de418cf99 stock_split-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+160bbe8565f066ff2e7565fd8a9aceec2c3a0bed stock_split-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+51f597bea6844c61a7dd658329a0e55e011e5327 stock_split-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+f13147d0020a5a42a7420db6678d2472ccf79bd3 stock_split-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+69d98ca60d7117c6ea722ea3d69fb7896859614b stock_split-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+5cda0f5b743d0d42a58187e5d38585e5e4ec7f1d stock_split-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+3e649b6f6f2a16621caa05565ffcc8934bcb308e stock_split-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+ca9aef457838d9bae9cddc270e83239c3d08dfde stock_split-6.6.0
+2c1e13c8dd3396c1cd8e638111aac955de3ebc00 1.2.0
+5295eef207dc90e5cd3667c3883675e05726ef57 1.4.0
+2dfd00186d72076cf13379297e19c076884078d9 1.6.0
+056794451985f57a11e3cd7eba52f596ee9ec735 1.8.0
+bd08fecfa2cf0e7e3580c85090f62e1711fcfb88 2.0.0
+fe083045a79de94717fd58ecfa407f9662d05445 2.2.0
+926d98699fe8374bf591a6a21561cb51af46b3cb 2.4.0
+5169c4780f85a719ae92808f229620867a6756ca 2.6.0
+bc954fb77cc0651892cdfe10fb52fda48c238a98 2.8.0
+bb15a9f03156fea571be3216d502e5d4dc92439c 3.0.0
+7887dba041046609d589e9db4d3d6cf154d84865 3.2.0
+13c061d1e265b64a17a67ab05b2419ea17a10e7b 3.4.0
+8cd9280b5c4df641c5c969f020cec2d7d291082e 3.6.0
+3cd313fcfb1603d6ba340e254fc09ac6cfd1c420 3.8.0
+f36bf15e0049da995257277971560f979e534808 4.0.0
+a0f86fdcff3f7146eba32e4c06107cbadf7e52e5 4.2.0
+33bc557f7dde9e3ed40d6cc8e11b98eda63239a5 4.4.0
+32bafb5576e02e637109040302e14ff20f32e3a4 4.6.0
+1567de11c58a7052bba71f735826f332ece9ef35 4.8.0
+30611743f9cfe3c23bf8d252b971b011ea54ad53 5.0.0
+39be3138aa4546c555cf9ca5d800bb4ec3c3d7cb 5.2.0
+91f140df04060667e5faab3bf8d1095cab3f5528 5.4.0
+dbec1eac9dc4167e1307adbc62ef72bc7937d5ef 5.6.0
+00c0bad66396daf07d8c5f78dd8dae4ed0e421a4 5.8.0
+5a0e8f4810783920576928b183e3733693959da8 6.0.0
+a19ed98c7d062115451f9ed8d1e5c09017cd6b72 6.2.0
+ec2dcacd13e91cae985e8a259459a2a1c1185cae 6.4.0
+49793239a5c3e08cb3dd39e43642826b3f692f26 6.6.0
+0000000000000000000000000000000000000000 1.2.0
+2c1e13c8dd3396c1cd8e638111aac955de3ebc00 stock_supply_day-1.2.0
+0000000000000000000000000000000000000000 1.4.0
+5295eef207dc90e5cd3667c3883675e05726ef57 stock_supply_day-1.4.0
+0000000000000000000000000000000000000000 1.6.0
+2dfd00186d72076cf13379297e19c076884078d9 stock_supply_day-1.6.0
+0000000000000000000000000000000000000000 1.8.0
+056794451985f57a11e3cd7eba52f596ee9ec735 stock_supply_day-1.8.0
+0000000000000000000000000000000000000000 2.0.0
+bd08fecfa2cf0e7e3580c85090f62e1711fcfb88 stock_supply_day-2.0.0
+0000000000000000000000000000000000000000 2.2.0
+fe083045a79de94717fd58ecfa407f9662d05445 stock_supply_day-2.2.0
+0000000000000000000000000000000000000000 2.4.0
+926d98699fe8374bf591a6a21561cb51af46b3cb stock_supply_day-2.4.0
+0000000000000000000000000000000000000000 2.6.0
+5169c4780f85a719ae92808f229620867a6756ca stock_supply_day-2.6.0
+0000000000000000000000000000000000000000 2.8.0
+bc954fb77cc0651892cdfe10fb52fda48c238a98 stock_supply_day-2.8.0
+0000000000000000000000000000000000000000 3.0.0
+bb15a9f03156fea571be3216d502e5d4dc92439c stock_supply_day-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+7887dba041046609d589e9db4d3d6cf154d84865 stock_supply_day-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+13c061d1e265b64a17a67ab05b2419ea17a10e7b stock_supply_day-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+8cd9280b5c4df641c5c969f020cec2d7d291082e stock_supply_day-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+3cd313fcfb1603d6ba340e254fc09ac6cfd1c420 stock_supply_day-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+f36bf15e0049da995257277971560f979e534808 stock_supply_day-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+a0f86fdcff3f7146eba32e4c06107cbadf7e52e5 stock_supply_day-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+33bc557f7dde9e3ed40d6cc8e11b98eda63239a5 stock_supply_day-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+32bafb5576e02e637109040302e14ff20f32e3a4 stock_supply_day-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+1567de11c58a7052bba71f735826f332ece9ef35 stock_supply_day-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+30611743f9cfe3c23bf8d252b971b011ea54ad53 stock_supply_day-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+39be3138aa4546c555cf9ca5d800bb4ec3c3d7cb stock_supply_day-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+91f140df04060667e5faab3bf8d1095cab3f5528 stock_supply_day-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+dbec1eac9dc4167e1307adbc62ef72bc7937d5ef stock_supply_day-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+00c0bad66396daf07d8c5f78dd8dae4ed0e421a4 stock_supply_day-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+5a0e8f4810783920576928b183e3733693959da8 stock_supply_day-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+a19ed98c7d062115451f9ed8d1e5c09017cd6b72 stock_supply_day-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+ec2dcacd13e91cae985e8a259459a2a1c1185cae stock_supply_day-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+49793239a5c3e08cb3dd39e43642826b3f692f26 stock_supply_day-6.6.0
+0834d76da22334e9c2b1e9d89ba50ac38bd3907f 2.2.0
+3c285f5f45031efbf9966541ace27b80fa45129d 2.4.0
+850476a6cbe95cf9bead5fdfaf094231908623ae 2.6.0
+3e0634468842969d6b2ee5e0f0c69a5aa75088e0 2.8.0
+3a26b77c883afebe780e59cd591c85f86248479c 3.0.0
+e6944d53c9579ff7d529f2fcadc021dc5a96d76c 3.2.0
+749efb5e0a4e86fb5ce3d5f181e73bc61ccd40e8 3.4.0
+370823db908f443f81bae475974c57af6281236b 3.6.0
+ba552f7b9b5297a6cde2372eebc523945d535c93 3.8.0
+0c88f450cac4029d9aaa81e94bc24457aec7c54a 4.0.0
+f0df25bfdb09fc1875f336bb870aa140a3247bcd 4.2.0
+afc2f1896f1c22b4591147b48f03743886e390f2 4.4.0
+5d6cdbfbb2b37451d4875ff9e789bf1350e75ab7 4.6.0
+df25bbcc27ede6b2a09868c7239732c3cd5e2c2a 4.8.0
+df42ccdd98a6fb0b4f55cc24e94f077fec1ffeb2 5.0.0
+d8a1fdd9db7f020437f2d5f02311ab29fe0cbab4 5.2.0
+c4c090246916fe2e00d67a26cb9859ea0a7106b5 5.4.0
+b89599b1cef0267371ce55e1b41cb1958d3312ba 5.6.0
+757b5e5484dd448afcbec95e87c21ecfad938b5f 5.8.0
+579edbea3863be427cfc1bb76cec03d061732d90 6.0.0
+e979007c21a4054f31741b30aed287cd5a638ebe 6.2.0
+91add9ae71e1343bccacf5479b71eb0108eb4de1 6.4.0
+1c7acdc192cc44cb913b7aa9165062b1cb1d8873 6.6.0
+0000000000000000000000000000000000000000 2.2.0
+0834d76da22334e9c2b1e9d89ba50ac38bd3907f stock_supply_forecast-2.2.0
+0000000000000000000000000000000000000000 2.4.0
+3c285f5f45031efbf9966541ace27b80fa45129d stock_supply_forecast-2.4.0
+0000000000000000000000000000000000000000 2.6.0
+850476a6cbe95cf9bead5fdfaf094231908623ae stock_supply_forecast-2.6.0
+0000000000000000000000000000000000000000 2.8.0
+3e0634468842969d6b2ee5e0f0c69a5aa75088e0 stock_supply_forecast-2.8.0
+0000000000000000000000000000000000000000 3.0.0
+3a26b77c883afebe780e59cd591c85f86248479c stock_supply_forecast-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+e6944d53c9579ff7d529f2fcadc021dc5a96d76c stock_supply_forecast-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+749efb5e0a4e86fb5ce3d5f181e73bc61ccd40e8 stock_supply_forecast-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+370823db908f443f81bae475974c57af6281236b stock_supply_forecast-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+ba552f7b9b5297a6cde2372eebc523945d535c93 stock_supply_forecast-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+0c88f450cac4029d9aaa81e94bc24457aec7c54a stock_supply_forecast-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+f0df25bfdb09fc1875f336bb870aa140a3247bcd stock_supply_forecast-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+afc2f1896f1c22b4591147b48f03743886e390f2 stock_supply_forecast-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+5d6cdbfbb2b37451d4875ff9e789bf1350e75ab7 stock_supply_forecast-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+df25bbcc27ede6b2a09868c7239732c3cd5e2c2a stock_supply_forecast-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+df42ccdd98a6fb0b4f55cc24e94f077fec1ffeb2 stock_supply_forecast-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+d8a1fdd9db7f020437f2d5f02311ab29fe0cbab4 stock_supply_forecast-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+c4c090246916fe2e00d67a26cb9859ea0a7106b5 stock_supply_forecast-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+b89599b1cef0267371ce55e1b41cb1958d3312ba stock_supply_forecast-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+757b5e5484dd448afcbec95e87c21ecfad938b5f stock_supply_forecast-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+579edbea3863be427cfc1bb76cec03d061732d90 stock_supply_forecast-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+e979007c21a4054f31741b30aed287cd5a638ebe stock_supply_forecast-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+91add9ae71e1343bccacf5479b71eb0108eb4de1 stock_supply_forecast-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+1c7acdc192cc44cb913b7aa9165062b1cb1d8873 stock_supply_forecast-6.6.0
+bb2bb6af62f06218b0c8c689b24dd16f43307ca1 1.0.0
+5b0a8261963f167230f23a1b97c8b38519428143 1.2.0
+396ad2807deb26c6c353eb119dc50fd4fdcbb28a 1.4.0
+b44aa993ce24453fdb2362187e201a9375bcaa09 1.6.0
+f76056df60f581f803c7a7e4cec81397e4bbbb9c 1.8.0
+354dfc672c4b3ee2609a4051f6d8d431dd087231 2.0.0
+0881ad5cb82f3f00ec1eea276fa100a957691982 2.2.0
+5eb0f23e5774dddbf43cafe34bf527e1cd78d619 2.4.0
+6cd5f943826cb858bc34d20074bfd81b715114f8 2.6.0
+69f57817f6f0ed6ee0788cfab959a9321fcb45bb 2.8.0
+2ebe2636b804a2f7635d0af5b1030ced08de7a37 3.0.0
+c466a41ecc7586e898f0f4f2341c2e74b41ea816 3.2.0
+ddd6516306dd09e3049fb95ff94b4ce48687e200 3.4.0
+e122da9f78841562722820efbf4d64e4c390e8af 3.6.0
+5dcc2dd84f2145e78882af143cad5111c31f09b6 3.8.0
+c0a58dc8306d6885126b9613ad4b36e0a95b75f0 4.0.0
+afc53d87c88438c9c8e56629e994836844e32dbe 4.2.0
+7bbc6abdafa0642baf4095654151d70c9e5482c4 4.4.0
+99eaaa78814833e4d21e9d96e8c110f061f0edfa 4.6.0
+3b5c655f3c26831a505bd74493f108425d42bc62 4.8.0
+1c163e9beae826b96a72cd0d2c59bf4899241f82 5.0.0
+c139a716d188bf7fbf46574fa84a473133b8bee2 5.2.0
+9264fc010a2d2acb3128d9208977bd6b77fb5160 5.4.0
+2d2feece662966a006078304aa61b695447cef2f 5.6.0
+5756606b07d016272254398e15ae07873a72c230 5.8.0
+d527c60bfe0bc723779200d118179faa7f96ba4a 6.0.0
+0a8b4ee3edc6e4e4e128884c435a47108ef30ba2 6.2.0
+e87dde891cebd2a9c913e1d4ed1884010123e740 6.4.0
+833a1c72275774e303e72d99b8c79f61a4aa873b 6.6.0
+0000000000000000000000000000000000000000 1.0.0
+bb2bb6af62f06218b0c8c689b24dd16f43307ca1 stock_supply-1.0.0
+0000000000000000000000000000000000000000 1.2.0
+5b0a8261963f167230f23a1b97c8b38519428143 stock_supply-1.2.0
+0000000000000000000000000000000000000000 1.4.0
+396ad2807deb26c6c353eb119dc50fd4fdcbb28a stock_supply-1.4.0
+0000000000000000000000000000000000000000 1.6.0
+b44aa993ce24453fdb2362187e201a9375bcaa09 stock_supply-1.6.0
+0000000000000000000000000000000000000000 1.8.0
+f76056df60f581f803c7a7e4cec81397e4bbbb9c stock_supply-1.8.0
+0000000000000000000000000000000000000000 2.0.0
+354dfc672c4b3ee2609a4051f6d8d431dd087231 stock_supply-2.0.0
+0000000000000000000000000000000000000000 2.2.0
+0881ad5cb82f3f00ec1eea276fa100a957691982 stock_supply-2.2.0
+0000000000000000000000000000000000000000 2.4.0
+5eb0f23e5774dddbf43cafe34bf527e1cd78d619 stock_supply-2.4.0
+0000000000000000000000000000000000000000 2.6.0
+6cd5f943826cb858bc34d20074bfd81b715114f8 stock_supply-2.6.0
+0000000000000000000000000000000000000000 2.8.0
+69f57817f6f0ed6ee0788cfab959a9321fcb45bb stock_supply-2.8.0
+0000000000000000000000000000000000000000 3.0.0
+2ebe2636b804a2f7635d0af5b1030ced08de7a37 stock_supply-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+c466a41ecc7586e898f0f4f2341c2e74b41ea816 stock_supply-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+ddd6516306dd09e3049fb95ff94b4ce48687e200 stock_supply-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+e122da9f78841562722820efbf4d64e4c390e8af stock_supply-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+5dcc2dd84f2145e78882af143cad5111c31f09b6 stock_supply-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+c0a58dc8306d6885126b9613ad4b36e0a95b75f0 stock_supply-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+afc53d87c88438c9c8e56629e994836844e32dbe stock_supply-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+7bbc6abdafa0642baf4095654151d70c9e5482c4 stock_supply-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+99eaaa78814833e4d21e9d96e8c110f061f0edfa stock_supply-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+3b5c655f3c26831a505bd74493f108425d42bc62 stock_supply-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+1c163e9beae826b96a72cd0d2c59bf4899241f82 stock_supply-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+c139a716d188bf7fbf46574fa84a473133b8bee2 stock_supply-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+9264fc010a2d2acb3128d9208977bd6b77fb5160 stock_supply-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+2d2feece662966a006078304aa61b695447cef2f stock_supply-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+5756606b07d016272254398e15ae07873a72c230 stock_supply-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+d527c60bfe0bc723779200d118179faa7f96ba4a stock_supply-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+0a8b4ee3edc6e4e4e128884c435a47108ef30ba2 stock_supply-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+e87dde891cebd2a9c913e1d4ed1884010123e740 stock_supply-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+833a1c72275774e303e72d99b8c79f61a4aa873b stock_supply-6.6.0
+ec2752f736f671fea3f95f881fa19e7cbfcc88c2 2.4.0
+4541105a8fc9586b5c65f581d70dd6906c41a730 2.6.0
+c0a9cb20a609d38ecf4facd08ffe55b2020e38ad 2.8.0
+ddf4cfa5af01e368d995885606d572d53d36cd7b 3.0.0
+81e986b99d1b16b26e8c7ae69684225bfa252603 3.2.0
+808383c0929c8dda2fab252418dbf31b46c2dffc 3.4.0
+bf11ecaa1d599160a62a02f46639955aaaa472a3 3.6.0
+07c3ef01edffc285a49cb969e18737dfac67bfdc 3.8.0
+d41ca7fbc924d4f73aff1c8377d2f700abe06f2d 4.0.0
+b58e60f41b662ac3d58c7502c4a6b4d5018797f4 4.2.0
+52078228f2c56880ac08f6987e8383c08a8043fd 4.4.0
+5df3455491d72296ada960cb45f72a276433a45d 4.6.0
+769117cd528a585fda8ea67bad5b54bf6fe5f6a6 4.8.0
+25c05b49d46071031d53a7798a711246789d6973 5.0.0
+24c941bdf02946e4bc130135508158dcb9817c39 5.2.0
+d4b5b3fa95da83bb9439320e69f4df43b9360f9c 5.4.0
+0b460de8ca80a58dc7b4d4528c6c4587fa0d16eb 5.6.0
+f0209c41aa97aaf6a1c8da050e47f24ad289aa38 5.8.0
+6f70ee75254fa62addab73552b06b39a2e151e66 6.0.0
+6311d85f112ab42e976db5964c3b8a88f71c609d 6.2.0
+df757189f2c2803cbd60aa4646ec073712ad2a72 6.4.0
+a10a03c01c293c3d60338c0cdf255e645ae582bc 6.6.0
+0000000000000000000000000000000000000000 2.4.0
+ec2752f736f671fea3f95f881fa19e7cbfcc88c2 stock_supply_production-2.4.0
+0000000000000000000000000000000000000000 2.6.0
+4541105a8fc9586b5c65f581d70dd6906c41a730 stock_supply_production-2.6.0
+0000000000000000000000000000000000000000 2.8.0
+c0a9cb20a609d38ecf4facd08ffe55b2020e38ad stock_supply_production-2.8.0
+0000000000000000000000000000000000000000 3.0.0
+ddf4cfa5af01e368d995885606d572d53d36cd7b stock_supply_production-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+81e986b99d1b16b26e8c7ae69684225bfa252603 stock_supply_production-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+808383c0929c8dda2fab252418dbf31b46c2dffc stock_supply_production-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+bf11ecaa1d599160a62a02f46639955aaaa472a3 stock_supply_production-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+07c3ef01edffc285a49cb969e18737dfac67bfdc stock_supply_production-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+d41ca7fbc924d4f73aff1c8377d2f700abe06f2d stock_supply_production-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+b58e60f41b662ac3d58c7502c4a6b4d5018797f4 stock_supply_production-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+52078228f2c56880ac08f6987e8383c08a8043fd stock_supply_production-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+5df3455491d72296ada960cb45f72a276433a45d stock_supply_production-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+769117cd528a585fda8ea67bad5b54bf6fe5f6a6 stock_supply_production-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+25c05b49d46071031d53a7798a711246789d6973 stock_supply_production-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+24c941bdf02946e4bc130135508158dcb9817c39 stock_supply_production-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+d4b5b3fa95da83bb9439320e69f4df43b9360f9c stock_supply_production-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+0b460de8ca80a58dc7b4d4528c6c4587fa0d16eb stock_supply_production-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+f0209c41aa97aaf6a1c8da050e47f24ad289aa38 stock_supply_production-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+6f70ee75254fa62addab73552b06b39a2e151e66 stock_supply_production-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+6311d85f112ab42e976db5964c3b8a88f71c609d stock_supply_production-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+df757189f2c2803cbd60aa4646ec073712ad2a72 stock_supply_production-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+a10a03c01c293c3d60338c0cdf255e645ae582bc stock_supply_production-6.6.0
+b9082c1aa7e6cc8316754bca8f2b29c7018ef9fc 3.0.0
+1dbac5dcf15dc3f17fb4865387a9e171dd20fc70 3.2.0
+db5b4bb6b6b098dd55089c2923e3eb5e1b8ec56b 3.4.0
+b7cb20ab4ec3b50821983ed8c0b034f30752a6ec 3.6.0
+7961a5a68240535525babbcdf496952107a480bf 3.8.0
+615333cf31aa9cc78cba9d7e20c515752e448fdb 4.0.0
+eaf2542a8adbf470a3249429f44cd5c70fa6a986 4.2.0
+6bd47a06f582784dfca255c49c7877d614adec51 4.4.0
+486b4928c849a93beb92d3bdfecfc8f622a38956 4.6.0
+03ded560c597cabf1a3e7df1fb586ecde33c1529 4.8.0
+7fcc5447286ed6be08252a52014a229fb21e706b 5.0.0
+25dfcaa29bcd9d57cdf019b3cae55b6226c355f6 5.2.0
+d4b86ad1ba39b874c39da9a5a007690489f4e15f 5.4.0
+f55c3c6bdd16d4b2ce85c8d691e9cafa71ce3d1f 5.6.0
+74c459fcf1a4a1237e25c4e3a63adbed65a7d1a8 5.8.0
+71a5bc1d16dc5b2b613ab21d94116f74d3b99320 6.0.0
+c7e966206f80f8ec35d48cada0dbf93603d2ba58 6.2.0
+8326eead85e5b3dbae373141494cf52ac0ee1868 6.4.0
+0e2e8692cf07cdbc798c4ba525b7184633c26635 6.6.0
+0000000000000000000000000000000000000000 3.0.0
+b9082c1aa7e6cc8316754bca8f2b29c7018ef9fc timesheet_cost-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+1dbac5dcf15dc3f17fb4865387a9e171dd20fc70 timesheet_cost-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+db5b4bb6b6b098dd55089c2923e3eb5e1b8ec56b timesheet_cost-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+b7cb20ab4ec3b50821983ed8c0b034f30752a6ec timesheet_cost-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+7961a5a68240535525babbcdf496952107a480bf timesheet_cost-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+615333cf31aa9cc78cba9d7e20c515752e448fdb timesheet_cost-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+eaf2542a8adbf470a3249429f44cd5c70fa6a986 timesheet_cost-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+6bd47a06f582784dfca255c49c7877d614adec51 timesheet_cost-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+486b4928c849a93beb92d3bdfecfc8f622a38956 timesheet_cost-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+03ded560c597cabf1a3e7df1fb586ecde33c1529 timesheet_cost-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+7fcc5447286ed6be08252a52014a229fb21e706b timesheet_cost-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+25dfcaa29bcd9d57cdf019b3cae55b6226c355f6 timesheet_cost-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+d4b86ad1ba39b874c39da9a5a007690489f4e15f timesheet_cost-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+f55c3c6bdd16d4b2ce85c8d691e9cafa71ce3d1f timesheet_cost-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+74c459fcf1a4a1237e25c4e3a63adbed65a7d1a8 timesheet_cost-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+71a5bc1d16dc5b2b613ab21d94116f74d3b99320 timesheet_cost-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+c7e966206f80f8ec35d48cada0dbf93603d2ba58 timesheet_cost-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+8326eead85e5b3dbae373141494cf52ac0ee1868 timesheet_cost-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+0e2e8692cf07cdbc798c4ba525b7184633c26635 timesheet_cost-6.6.0
+a32068d131a6872da6c87812f3fda96c5ad076bb 1.4.0
+3d405f7a2a43e41869b7f438203d3a945b1d68f9 1.6.0
+65577163f1e51a0e1385155cae93eb2900866f3b 1.8.0
+24d03108a830bc2b71924432ebcb32dfd6f5b2e0 2.0.0
+1d020661487e0ddc14d2825aa66ec6772e66010c 2.2.0
+7b90dcce007c3fc93a9b409f54f379f8182728ee 2.4.0
+549128cae2441f891c24176c1f6a67777962e3d3 2.6.0
+8c69d08939dbc773d89f4c637ce6a8d8cadcb866 2.8.0
+4e635a95118453b2ff0ec533a70ac50d4dacc3cb 3.0.0
+5f4ed300d4966e0c16c4497428a130b19a6209f3 3.2.0
+a4e84c96f4735bd710e02a0364af0947ba44d4b7 3.4.0
+728c1ee800a32fdd4856e86998a32c3c929d262d 3.6.0
+1924468dda905272353c147edc625a3496b3421e 3.8.0
+ae80ff03e20174f8ed595b9fa47893598c13f91f 4.0.0
+dd6dfdad58d95b23dab3c1ff906f2e18c634b474 4.2.0
+05cf4e50160ca0801ef2aa7c93d2b9b9c4a41071 4.4.0
+4ad8501eef3e1b47ccf54ecabf5cedbb0bebe99b 4.6.0
+bd8398d102d53692be26bd76171c23b85676304c 4.8.0
+f22152a613c52f8ffece522ec3a1f30e46637e3a 5.0.0
+ae0426e8137939d8d4e14f0d6717b46e0bd6ff3a 5.2.0
+41c1f6178f3f039bc62dd85ebd1fa6f92212c9ec 5.4.0
+f9ad969ee981b3b7cd11723d471d4ed3d0fff873 5.6.0
+a874b70acc06493a4b64edc59ec3be3cba8503a6 5.8.0
+779126589e978c55a09cc15d7854a08fff370416 6.0.0
+562ea339e5f31405a6835b76cd0b0f85541bbe0f 6.2.0
+3c80653500553e4f032caf920c5e0b515dfbdcf0 6.4.0
+c16ea65a1df9fc825f2f929cf47e733dadc73b80 6.6.0
+0000000000000000000000000000000000000000 1.4.0
+a32068d131a6872da6c87812f3fda96c5ad076bb timesheet-1.4.0
+0000000000000000000000000000000000000000 1.6.0
+3d405f7a2a43e41869b7f438203d3a945b1d68f9 timesheet-1.6.0
+0000000000000000000000000000000000000000 1.8.0
+65577163f1e51a0e1385155cae93eb2900866f3b timesheet-1.8.0
+0000000000000000000000000000000000000000 2.0.0
+24d03108a830bc2b71924432ebcb32dfd6f5b2e0 timesheet-2.0.0
+0000000000000000000000000000000000000000 2.2.0
+1d020661487e0ddc14d2825aa66ec6772e66010c timesheet-2.2.0
+0000000000000000000000000000000000000000 2.4.0
+7b90dcce007c3fc93a9b409f54f379f8182728ee timesheet-2.4.0
+0000000000000000000000000000000000000000 2.6.0
+549128cae2441f891c24176c1f6a67777962e3d3 timesheet-2.6.0
+0000000000000000000000000000000000000000 2.8.0
+8c69d08939dbc773d89f4c637ce6a8d8cadcb866 timesheet-2.8.0
+0000000000000000000000000000000000000000 3.0.0
+4e635a95118453b2ff0ec533a70ac50d4dacc3cb timesheet-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+5f4ed300d4966e0c16c4497428a130b19a6209f3 timesheet-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+a4e84c96f4735bd710e02a0364af0947ba44d4b7 timesheet-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+728c1ee800a32fdd4856e86998a32c3c929d262d timesheet-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+1924468dda905272353c147edc625a3496b3421e timesheet-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+ae80ff03e20174f8ed595b9fa47893598c13f91f timesheet-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+dd6dfdad58d95b23dab3c1ff906f2e18c634b474 timesheet-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+05cf4e50160ca0801ef2aa7c93d2b9b9c4a41071 timesheet-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+4ad8501eef3e1b47ccf54ecabf5cedbb0bebe99b timesheet-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+bd8398d102d53692be26bd76171c23b85676304c timesheet-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+f22152a613c52f8ffece522ec3a1f30e46637e3a timesheet-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+ae0426e8137939d8d4e14f0d6717b46e0bd6ff3a timesheet-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+41c1f6178f3f039bc62dd85ebd1fa6f92212c9ec timesheet-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+f9ad969ee981b3b7cd11723d471d4ed3d0fff873 timesheet-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+a874b70acc06493a4b64edc59ec3be3cba8503a6 timesheet-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+779126589e978c55a09cc15d7854a08fff370416 timesheet-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+562ea339e5f31405a6835b76cd0b0f85541bbe0f timesheet-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+3c80653500553e4f032caf920c5e0b515dfbdcf0 timesheet-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+c16ea65a1df9fc825f2f929cf47e733dadc73b80 timesheet-6.6.0
+0f3d5527aad7e83e07c84b19983b86f5b580d9b9 5.2.0
+32c3f6707c841e89eaa8e1200b4ed4b4b8c2510d 5.4.0
+65a1ddcc0b7d681c785f9260aa11e9c9a9b3f74b 5.6.0
+8766a61dd6f885faa2bed9eaa21c307412674989 5.8.0
+5c50392d0b77f4f5c1f76ece0997ec73591e887c 6.0.0
+111e976e7d587ab314808f3be9508fb45fcb7218 6.2.0
+8b0f3f4c817cbf75622b0e2cca36c7d32a2e71ca 6.4.0
+9a8161d1a043fa99953350890026644a36adc927 6.6.0
+0000000000000000000000000000000000000000 5.2.0
+0f3d5527aad7e83e07c84b19983b86f5b580d9b9 user_role-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+32c3f6707c841e89eaa8e1200b4ed4b4b8c2510d user_role-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+65a1ddcc0b7d681c785f9260aa11e9c9a9b3f74b user_role-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+8766a61dd6f885faa2bed9eaa21c307412674989 user_role-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+5c50392d0b77f4f5c1f76ece0997ec73591e887c user_role-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+111e976e7d587ab314808f3be9508fb45fcb7218 user_role-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+8b0f3f4c817cbf75622b0e2cca36c7d32a2e71ca user_role-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+9a8161d1a043fa99953350890026644a36adc927 user_role-6.6.0
+cc6273db844d391455840a0cb63fbd8e78b704c7 5.8.0
+4020d5ca9497c14dfc273676d49363650eb8da80 6.0.0
+2f7384935c9a660fe3e324dd80cae3231058dbfd 6.2.0
+2c401c41ecfbb40b9d175ea27ead1dfc28808d7d 6.4.0
+2e6be173a48ec7586d87bf8d4277d90e45f9e421 6.6.0
+0000000000000000000000000000000000000000 5.8.0
+cc6273db844d391455840a0cb63fbd8e78b704c7 web_shop-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+4020d5ca9497c14dfc273676d49363650eb8da80 web_shop-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+2f7384935c9a660fe3e324dd80cae3231058dbfd web_shop-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+2c401c41ecfbb40b9d175ea27ead1dfc28808d7d web_shop-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+2e6be173a48ec7586d87bf8d4277d90e45f9e421 web_shop-6.6.0
+0fa3353dd8f6ecd194c8850181ed067e33f12a9c 6.2.0
+48e0025a6f396470511abd211e8454cf5b007b68 6.4.0
+fefaf7d877521704862965f443572c2df19d0fa0 6.6.0
+0000000000000000000000000000000000000000 6.2.0
+0fa3353dd8f6ecd194c8850181ed067e33f12a9c web_shop_shopify-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+48e0025a6f396470511abd211e8454cf5b007b68 web_shop_shopify-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+fefaf7d877521704862965f443572c2df19d0fa0 web_shop_shopify-6.6.0
+bfc8e45097fc0e414744408e96708fdf5d2b33a1 5.8.0
+2efa183d80e356d0c11731819456b8dd9bc586db 6.0.0
+68ad2bbc8a5c7be8f7e28abfc29643c50edeae72 6.2.0
+4c49fb91d23f62bcec4079bd4329cc6011a0762d 6.4.0
+a1f0befe30d33598a618410c7ab38831ae8d99b9 6.6.0
+0000000000000000000000000000000000000000 5.8.0
+bfc8e45097fc0e414744408e96708fdf5d2b33a1 web_shop_vue_storefront-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+2efa183d80e356d0c11731819456b8dd9bc586db web_shop_vue_storefront-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+68ad2bbc8a5c7be8f7e28abfc29643c50edeae72 web_shop_vue_storefront-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+4c49fb91d23f62bcec4079bd4329cc6011a0762d web_shop_vue_storefront-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+a1f0befe30d33598a618410c7ab38831ae8d99b9 web_shop_vue_storefront-6.6.0
+0a5ab9e8e526e89b69c1aadb73127da0759edc27 5.8.0
+4b01e563d74ede2cd6ac3c0ae8bd597a963c21a3 6.0.0
+4aec6b591d561476f821e4b7696fdeb2445649a0 6.2.0
+13fb09e13f9961147b3fafd7a4acda34aa782057 6.4.0
+69ebe443a0a7202973e896d6a44a62a2fff29615 6.6.0
+0000000000000000000000000000000000000000 5.8.0
+0a5ab9e8e526e89b69c1aadb73127da0759edc27 web_shop_vue_storefront_stripe-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+4b01e563d74ede2cd6ac3c0ae8bd597a963c21a3 web_shop_vue_storefront_stripe-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+4aec6b591d561476f821e4b7696fdeb2445649a0 web_shop_vue_storefront_stripe-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+13fb09e13f9961147b3fafd7a4acda34aa782057 web_shop_vue_storefront_stripe-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+69ebe443a0a7202973e896d6a44a62a2fff29615 web_shop_vue_storefront_stripe-6.6.0
+d1340478469878c66528aac5cec001841d14ca5a 5.2.0
+bed84c6dd812463897dc9cca5b7909f6ea4651a4 5.4.0
+e37a9b2291b9b60d453a9eabc894d21b5aeca097 5.6.0
+c3046a83c61339a6310b8cf56c2e4dddd59a0675 5.8.0
+0d2662846f667e44e2831a271becf86f8868c9a5 6.0.0
+5a39f9619caf2338d2b86a46f16154a8e29d2830 6.2.0
+b27e5df8f64e7e96c3b895ec7090eb1bb9166eaa 6.4.0
+cd182550e175f7de15c5940fb446d72895f68a31 6.6.0
+0000000000000000000000000000000000000000 5.2.0
+d1340478469878c66528aac5cec001841d14ca5a web_shortener-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+bed84c6dd812463897dc9cca5b7909f6ea4651a4 web_shortener-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+e37a9b2291b9b60d453a9eabc894d21b5aeca097 web_shortener-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+c3046a83c61339a6310b8cf56c2e4dddd59a0675 web_shortener-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+0d2662846f667e44e2831a271becf86f8868c9a5 web_shortener-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+5a39f9619caf2338d2b86a46f16154a8e29d2830 web_shortener-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+b27e5df8f64e7e96c3b895ec7090eb1bb9166eaa web_shortener-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+cd182550e175f7de15c5940fb446d72895f68a31 web_shortener-6.6.0
+99f99784b341ce8bb34bd70d89f51aa45c24f1f7 4.2.0
+a6661fddc44d1cee9c5697d983e8fb38deb73225 4.4.0
+d5c1f780f492de8ab82da98a577a5685bb513d9b 4.6.0
+9ad3bd829ad68cd69806533416aadc50f5eb6794 4.8.0
+ca21f3a99b42b088c6588c36f5e105dae713f775 5.0.0
+c2ef0488218d9d3ee59514b744e2145bbd0147b3 5.2.0
+cb5da130470815adfd7b3681fa2803feed934f45 5.4.0
+b95009d0a58dd058440cc0cd7537e5c4499ea16a 5.6.0
+166c1e4c476baeb36b21cef7963b87b5ca07f71e 5.8.0
+ec9a4f3e26f796c12a267e4b3af717fd2a35c066 6.0.0
+355cdcd27f958fbd7e3bdd021c238283b3f0f539 6.2.0
+b81b890c871cea5a9a3fb734af72452f59969c32 6.4.0
+a9dab1237717b85084d19158a7d487d0d9adbfb4 6.6.0
+0000000000000000000000000000000000000000 4.2.0
+99f99784b341ce8bb34bd70d89f51aa45c24f1f7 web_user-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+a6661fddc44d1cee9c5697d983e8fb38deb73225 web_user-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+d5c1f780f492de8ab82da98a577a5685bb513d9b web_user-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+9ad3bd829ad68cd69806533416aadc50f5eb6794 web_user-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+ca21f3a99b42b088c6588c36f5e105dae713f775 web_user-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+c2ef0488218d9d3ee59514b744e2145bbd0147b3 web_user-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+cb5da130470815adfd7b3681fa2803feed934f45 web_user-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+b95009d0a58dd058440cc0cd7537e5c4499ea16a web_user-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+166c1e4c476baeb36b21cef7963b87b5ca07f71e web_user-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+ec9a4f3e26f796c12a267e4b3af717fd2a35c066 web_user-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+355cdcd27f958fbd7e3bdd021c238283b3f0f539 web_user-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+b81b890c871cea5a9a3fb734af72452f59969c32 web_user-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+a9dab1237717b85084d19158a7d487d0d9adbfb4 web_user-6.6.0
+3974f546b848d4ac59551db9f733d8ed62946dfd 1.8.0
+c8fdae3b2338b744fce709572958884a95de87b3 2.0.0
+120d0435125cf3a3c28280321962571924ad422f 2.2.0
+ef9846cb18afe62182de446d8e4fa7b8393f7168 2.4.0
+648c43939fd698988bde5b54f7a1dff9d47922af 2.6.0
+5625ce03643f9f2b69659907754e5b0e924c689f 2.8.0
+31740f7e08a0c449ce6715e1ef15392fb6326ce9 3.0.0
+40affcdda4629de37997d0e5c7d3fe9ca2806b12 3.2.0
+61013c4482fc95a61d2a15a8b21574a706755b10 3.4.0
+2a2503ebd25887ff3668d470809c00c5bcf2c6c7 3.6.0
+1e741a18e2a1f29fcc66e9ab4878554a4e63a355 3.8.0
+403f21dd1bb7059a0928c46c8b21a97c14f9c720 4.0.0
+d5b1e8f047748526d9a2cd354da0e86d617ec4c7 4.2.0
+365af7e74c2baae38e96bc0afb1deae2d2b44ac0 4.4.0
+cd4731fb373698d480a625a286de776a0b9bdc6e 4.6.0
+3867b51d50056fda52882150a017a9dce6811264 4.8.0
+e86f9d540f29dfcd39e8f198b50940c8b91250d6 5.0.0
+f4a0b0e282f39c013c44e5012e6b85e4b8a4ae40 5.2.0
+03daaf3994610fde107d98d8458b2731e03c5306 5.4.0
+a8061a1d268776766c44ceb97094d229dbe31962 5.6.0
+8bc88e82ff9edc33725d08bc0c6f2862f221a127 5.8.0
+ac15e7f1881fd78d30eac0d7c772638265830c77 6.0.0
+286ac00ea47d420641bf79917025421a90a5d353 6.2.0
+1310030ca59a2d88a3995cdc5874e9c4a57c5854 6.4.0
+051cf4dfddf8c0e15109b4a74554a910cc28c6c1 6.6.0
+0000000000000000000000000000000000000000 1.8.0
+3974f546b848d4ac59551db9f733d8ed62946dfd proteus-1.8.0
+0000000000000000000000000000000000000000 2.0.0
+c8fdae3b2338b744fce709572958884a95de87b3 proteus-2.0.0
+0000000000000000000000000000000000000000 2.2.0
+120d0435125cf3a3c28280321962571924ad422f proteus-2.2.0
+0000000000000000000000000000000000000000 2.4.0
+ef9846cb18afe62182de446d8e4fa7b8393f7168 proteus-2.4.0
+0000000000000000000000000000000000000000 2.6.0
+648c43939fd698988bde5b54f7a1dff9d47922af proteus-2.6.0
+0000000000000000000000000000000000000000 2.8.0
+5625ce03643f9f2b69659907754e5b0e924c689f proteus-2.8.0
+0000000000000000000000000000000000000000 3.0.0
+31740f7e08a0c449ce6715e1ef15392fb6326ce9 proteus-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+40affcdda4629de37997d0e5c7d3fe9ca2806b12 proteus-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+61013c4482fc95a61d2a15a8b21574a706755b10 proteus-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+2a2503ebd25887ff3668d470809c00c5bcf2c6c7 proteus-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+1e741a18e2a1f29fcc66e9ab4878554a4e63a355 proteus-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+403f21dd1bb7059a0928c46c8b21a97c14f9c720 proteus-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+d5b1e8f047748526d9a2cd354da0e86d617ec4c7 proteus-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+365af7e74c2baae38e96bc0afb1deae2d2b44ac0 proteus-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+cd4731fb373698d480a625a286de776a0b9bdc6e proteus-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+3867b51d50056fda52882150a017a9dce6811264 proteus-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+e86f9d540f29dfcd39e8f198b50940c8b91250d6 proteus-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+f4a0b0e282f39c013c44e5012e6b85e4b8a4ae40 proteus-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+03daaf3994610fde107d98d8458b2731e03c5306 proteus-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+a8061a1d268776766c44ceb97094d229dbe31962 proteus-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+8bc88e82ff9edc33725d08bc0c6f2862f221a127 proteus-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+ac15e7f1881fd78d30eac0d7c772638265830c77 proteus-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+286ac00ea47d420641bf79917025421a90a5d353 proteus-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+1310030ca59a2d88a3995cdc5874e9c4a57c5854 proteus-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+051cf4dfddf8c0e15109b4a74554a910cc28c6c1 proteus-6.6.0
+c835144ba5fd172c9aa8714683e69ca60bc894bc 3.8.0
+20712dc81634af43f9e0ebb41b0dcea50ccffdd2 4.0.0
+963504a30207af5877c11368ac5dadbc5d28fee1 4.2.0
+1fea2b717dd8d57d0a233c19d7f1eec35bdde0fa 4.4.0
+16a536201007ba66d36040a34e79a8998c4051f8 4.6.0
+08b000057b0b5a69f4034f2e1f5c7f2f7f23276f 4.8.0
+47edb75271514576ea775d28dc286a120675aa32 5.0.0
+4074fcefe73deec0b4dcd8b2e29f6c3c8eade611 5.2.0
+2d6d3a648c1dc1711adcc7bd3ff0930949b3076a 5.4.0
+513d2f77dc3bb1f5335af4faf233ccaa1711ac82 5.6.0
+e013e9930e2f27e5205b93f39d49f3604ae07901 5.8.0
+031cd536bd9f4e89345876c2d438626c57fbb33c 6.0.0
+e6b66ac38f2f3aefeddeba9fc0b3cee375d1f19a 6.2.0
+4a114b18bce58de90577d7975b0c275b45ecdcb0 6.4.0
+1bf438772b1bb9702ebb9bbcbce96f7ab53a94eb 6.6.0
+0000000000000000000000000000000000000000 3.8.0
+c835144ba5fd172c9aa8714683e69ca60bc894bc sao-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+20712dc81634af43f9e0ebb41b0dcea50ccffdd2 sao-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+963504a30207af5877c11368ac5dadbc5d28fee1 sao-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+1fea2b717dd8d57d0a233c19d7f1eec35bdde0fa sao-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+16a536201007ba66d36040a34e79a8998c4051f8 sao-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+08b000057b0b5a69f4034f2e1f5c7f2f7f23276f sao-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+47edb75271514576ea775d28dc286a120675aa32 sao-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+4074fcefe73deec0b4dcd8b2e29f6c3c8eade611 sao-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+2d6d3a648c1dc1711adcc7bd3ff0930949b3076a sao-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+513d2f77dc3bb1f5335af4faf233ccaa1711ac82 sao-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+e013e9930e2f27e5205b93f39d49f3604ae07901 sao-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+031cd536bd9f4e89345876c2d438626c57fbb33c sao-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+e6b66ac38f2f3aefeddeba9fc0b3cee375d1f19a sao-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+4a114b18bce58de90577d7975b0c275b45ecdcb0 sao-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+1bf438772b1bb9702ebb9bbcbce96f7ab53a94eb sao-6.6.0
+4b876ac37410e223bc3628256425d80398d051c6 4.8.0
+144f9950fba568bd77ac0eecd02c7b0d0a98ba87 5.0.0
+ed88584857aa1b39459a420270c0253d460cfe48 5.2.0
+ed46c63b027820aa6e605bb53040f4ed4d133813 5.4.0
+d2db68823a8225ff32842da4e948c1c01197e5cc 5.6.0
+eeab3256f17f6b9bc111d74d6d7f984e75d70f17 5.8.0
+4d33daf649c10711b782ef82b71e49d1a725ccee 6.0.0
+77df2082ed44a6655dd151c09cf8a7ca36ec6499 6.2.0
+88192dc708bc13b43a99168c97642106684bbfeb 6.4.0
+312583490fff372849dfb38c7c849325d40bbf81 6.6.0
+0000000000000000000000000000000000000000 4.8.0
+4b876ac37410e223bc3628256425d80398d051c6 trytond-gis-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+144f9950fba568bd77ac0eecd02c7b0d0a98ba87 trytond-gis-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+ed88584857aa1b39459a420270c0253d460cfe48 trytond-gis-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+ed46c63b027820aa6e605bb53040f4ed4d133813 trytond-gis-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+d2db68823a8225ff32842da4e948c1c01197e5cc trytond-gis-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+eeab3256f17f6b9bc111d74d6d7f984e75d70f17 trytond-gis-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+4d33daf649c10711b782ef82b71e49d1a725ccee trytond-gis-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+77df2082ed44a6655dd151c09cf8a7ca36ec6499 trytond-gis-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+88192dc708bc13b43a99168c97642106684bbfeb trytond-gis-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+312583490fff372849dfb38c7c849325d40bbf81 trytond-gis-6.6.0
+951bb3311b916cb893adc5294cfb3216d2940169 1.0.0
+9f5ce178a7c403a0865fd4b6c1a82a911df0e998 1.2.0
+e2d31d59de7745de70199b7c340d78b7c4775723 1.4.0
+64691214959ac19983f3b3d1dbb89ff693d1545c 1.6.0
+af3a6063b46bf8739a513a06400fbb9858b5869b 1.8.0
+3475040a8fe081b1b8609350186b779cc640fba4 2.0.0
+1df3f0702c621e65279af52d1f87725747ae8fa4 2.2.0
+640af4420c8eace7ee59a432bec54692f4808b20 2.4.0
+36530840a1d0dce354bbaa58ec849a409d306d83 2.6.0
+2893d6c3efd6df3759ab09a28ea16773a160118e 2.8.0
+759c6ff44b90b8c685e9d9a4124bcd85af204649 3.0.0
+b3d84aa2c3a6ed3b76bfb58a40fc687f68824c29 3.2.0
+f0a9fa755cde703be54efd747f376b096ea8316c 3.4.0
+1e4ba5a3f16e6afd59131b49841eb004e706619d 3.6.0
+0a29a9dba7f56fbdef067772eea3f037934999c9 3.8.0
+49a0caa894dae201ed4ec707f277d9859b5521fb 4.0.0
+eb8949ec5bcedba563b5799f1315a0cecfee61f6 4.2.0
+f253ce8ed02f4c46a69b8b2f29311ad8959698be 4.4.0
+e7a6d0e8002237f624ecc8a45a6a472f7baadd08 4.6.0
+321b0104a732419c11aa4926785502e0615b89c9 4.8.0
+e8cadc044d59edff8a2ca73932c723d507517ec8 5.0.0
+ef34e4e92d45ab2b2b2956bbb6aa8b3ca259eb13 5.2.0
+32170ff46339dbc8609225791ab737a0f3eb0291 5.4.0
+5738a22adbb45390167194e4089adc46c6b638a3 5.6.0
+e21456b81972188261b8a6fc876afc18f641c85b 5.8.0
+2164597ffa5f4f0443e4804944b30f5491070990 6.0.0
+1252631aa5277267887251090d6e2f7ed6d41503 6.2.0
+2593216de16bfca661479ed068b87fd0e83260e0 6.4.0
+e5934d7675cbdbf6e534ea4a01f9e1d0792e22b4 6.6.0
+0000000000000000000000000000000000000000 1.0.0
+951bb3311b916cb893adc5294cfb3216d2940169 trytond-1.0.0
+0000000000000000000000000000000000000000 1.2.0
+9f5ce178a7c403a0865fd4b6c1a82a911df0e998 trytond-1.2.0
+0000000000000000000000000000000000000000 1.4.0
+e2d31d59de7745de70199b7c340d78b7c4775723 trytond-1.4.0
+0000000000000000000000000000000000000000 1.6.0
+64691214959ac19983f3b3d1dbb89ff693d1545c trytond-1.6.0
+0000000000000000000000000000000000000000 1.8.0
+af3a6063b46bf8739a513a06400fbb9858b5869b trytond-1.8.0
+0000000000000000000000000000000000000000 2.0.0
+3475040a8fe081b1b8609350186b779cc640fba4 trytond-2.0.0
+0000000000000000000000000000000000000000 2.2.0
+1df3f0702c621e65279af52d1f87725747ae8fa4 trytond-2.2.0
+0000000000000000000000000000000000000000 2.4.0
+640af4420c8eace7ee59a432bec54692f4808b20 trytond-2.4.0
+0000000000000000000000000000000000000000 2.6.0
+36530840a1d0dce354bbaa58ec849a409d306d83 trytond-2.6.0
+0000000000000000000000000000000000000000 2.8.0
+2893d6c3efd6df3759ab09a28ea16773a160118e trytond-2.8.0
+0000000000000000000000000000000000000000 3.0.0
+759c6ff44b90b8c685e9d9a4124bcd85af204649 trytond-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+b3d84aa2c3a6ed3b76bfb58a40fc687f68824c29 trytond-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+f0a9fa755cde703be54efd747f376b096ea8316c trytond-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+1e4ba5a3f16e6afd59131b49841eb004e706619d trytond-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+0a29a9dba7f56fbdef067772eea3f037934999c9 trytond-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+49a0caa894dae201ed4ec707f277d9859b5521fb trytond-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+eb8949ec5bcedba563b5799f1315a0cecfee61f6 trytond-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+f253ce8ed02f4c46a69b8b2f29311ad8959698be trytond-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+e7a6d0e8002237f624ecc8a45a6a472f7baadd08 trytond-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+321b0104a732419c11aa4926785502e0615b89c9 trytond-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+e8cadc044d59edff8a2ca73932c723d507517ec8 trytond-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+ef34e4e92d45ab2b2b2956bbb6aa8b3ca259eb13 trytond-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+32170ff46339dbc8609225791ab737a0f3eb0291 trytond-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+5738a22adbb45390167194e4089adc46c6b638a3 trytond-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+e21456b81972188261b8a6fc876afc18f641c85b trytond-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+2164597ffa5f4f0443e4804944b30f5491070990 trytond-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+1252631aa5277267887251090d6e2f7ed6d41503 trytond-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+2593216de16bfca661479ed068b87fd0e83260e0 trytond-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+e5934d7675cbdbf6e534ea4a01f9e1d0792e22b4 trytond-6.6.0
+923b3073b686c6dc5a921d0561c934adf3eeb879 1.0.0
+9a6434d63616f46520b6fa1b2be31906ff6f4f6a 1.2.0
+de84c1443d4bad908eabb99c381578b988c2117f 1.4.0
+3976912b23dfc5db2525d4c2e55d17f099d9492d 1.6.0
+8aa050da53cbdfabe1353a37da91c011b7fff549 1.8.0
+1876747b3f963ba6011b4bcf6968e681624c6e24 2.0.0
+5364f8ca6cd2cccfb5f7f39c69bb20bae2b5f495 2.2.0
+fe15da23f7333e0e90d2693aadddf6bed53ed602 2.4.0
+d069f9f1cdc3fea39e71415268582abb2b333ea1 2.6.0
+21fbf8bd36096d926c472acfecd3963369204af8 2.8.0
+9197d90b0257ec7c4576a38092fd592b3e87f7a4 3.0.0
+9721289ee2fdaab8b990de9327c3eab87363c88c 3.2.0
+8e5cba59137f9d0a063fa6d7855e09a51bc5889c 3.4.0
+1ac658605d42d82988cfb232afebfe359aba7776 3.6.0
+f4b9c8a84cf61935afec788c3c639982731452ef 3.8.0
+44d8ed92ff90cf98c4c01d37f12d344d9d66e7f1 4.0.0
+94037cff031ef897c9533a579356977c8a3cf695 4.2.0
+763dc5d8e1d7e483edbf9977dd96afc114555555 4.4.0
+d7ed5002e47249d019fbc546f6ac562db44c54f2 4.6.0
+2a2b48ea60fbb5201ea12443000d3a106a2fa27c 4.8.0
+70ade9d1fe04c734fe2dd7d35dd75b13f1af902a 5.0.0
+d5652dee45a43fccc1f33d39050af6e00e073273 5.2.0
+9f3fbb33df184ca19350cc71054dd9afd55f1cb7 5.4.0
+45d3f736ffb4396ee0dac0e2110fcc17237337ba 5.6.0
+df9de0ceeb27b38b165da7526accad0ad6682e86 5.8.0
+d18d03f0c540dfd2aae81dfaac048378a62c0ef6 6.0.0
+932b5115f37ddb479b4034bf1438e48df198cc05 6.2.0
+4100f887dd4a3d7511c0c0547e766db7845114e3 6.4.0
+f3542b3396f897c2231e629437f528371d3d11db 6.6.0
+0000000000000000000000000000000000000000 1.0.0
+923b3073b686c6dc5a921d0561c934adf3eeb879 tryton-1.0.0
+0000000000000000000000000000000000000000 1.2.0
+9a6434d63616f46520b6fa1b2be31906ff6f4f6a tryton-1.2.0
+0000000000000000000000000000000000000000 1.4.0
+de84c1443d4bad908eabb99c381578b988c2117f tryton-1.4.0
+0000000000000000000000000000000000000000 1.6.0
+3976912b23dfc5db2525d4c2e55d17f099d9492d tryton-1.6.0
+0000000000000000000000000000000000000000 1.8.0
+8aa050da53cbdfabe1353a37da91c011b7fff549 tryton-1.8.0
+0000000000000000000000000000000000000000 2.0.0
+1876747b3f963ba6011b4bcf6968e681624c6e24 tryton-2.0.0
+0000000000000000000000000000000000000000 2.2.0
+5364f8ca6cd2cccfb5f7f39c69bb20bae2b5f495 tryton-2.2.0
+0000000000000000000000000000000000000000 2.4.0
+fe15da23f7333e0e90d2693aadddf6bed53ed602 tryton-2.4.0
+0000000000000000000000000000000000000000 2.6.0
+d069f9f1cdc3fea39e71415268582abb2b333ea1 tryton-2.6.0
+0000000000000000000000000000000000000000 2.8.0
+21fbf8bd36096d926c472acfecd3963369204af8 tryton-2.8.0
+0000000000000000000000000000000000000000 3.0.0
+9197d90b0257ec7c4576a38092fd592b3e87f7a4 tryton-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+9721289ee2fdaab8b990de9327c3eab87363c88c tryton-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+8e5cba59137f9d0a063fa6d7855e09a51bc5889c tryton-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+1ac658605d42d82988cfb232afebfe359aba7776 tryton-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+f4b9c8a84cf61935afec788c3c639982731452ef tryton-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+44d8ed92ff90cf98c4c01d37f12d344d9d66e7f1 tryton-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+94037cff031ef897c9533a579356977c8a3cf695 tryton-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+763dc5d8e1d7e483edbf9977dd96afc114555555 tryton-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+d7ed5002e47249d019fbc546f6ac562db44c54f2 tryton-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+2a2b48ea60fbb5201ea12443000d3a106a2fa27c tryton-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+70ade9d1fe04c734fe2dd7d35dd75b13f1af902a tryton-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+d5652dee45a43fccc1f33d39050af6e00e073273 tryton-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+9f3fbb33df184ca19350cc71054dd9afd55f1cb7 tryton-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+45d3f736ffb4396ee0dac0e2110fcc17237337ba tryton-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+df9de0ceeb27b38b165da7526accad0ad6682e86 tryton-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+d18d03f0c540dfd2aae81dfaac048378a62c0ef6 tryton-6.0.0
+0000000000000000000000000000000000000000 6.2.0
+932b5115f37ddb479b4034bf1438e48df198cc05 tryton-6.2.0
+0000000000000000000000000000000000000000 6.4.0
+4100f887dd4a3d7511c0c0547e766db7845114e3 tryton-6.4.0
+0000000000000000000000000000000000000000 6.6.0
+f3542b3396f897c2231e629437f528371d3d11db tryton-6.6.0
diff --git a/modules/stock_inventory_location/.drone.yml b/modules/stock_inventory_location/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_inventory_location/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_inventory_location/.flake8 b/modules/stock_inventory_location/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_inventory_location/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_inventory_location/.isort.cfg b/modules/stock_inventory_location/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_inventory_location/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_inventory_location/CHANGELOG b/modules/stock_inventory_location/CHANGELOG
new file mode 100644
index 0000000000..5524a0cd40
--- /dev/null
+++ b/modules/stock_inventory_location/CHANGELOG
@@ -0,0 +1,90 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+* Add empty quantity and complete lines options
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+
+Version 4.2.0 - 2016-11-28
+* Bug fixes (see mercurial logs for details)
+
+Version 4.0.0 - 2016-05-02
+* Bug fixes (see mercurial logs for details)
+* Add Python3 support
+
+Version 3.8.0 - 2015-11-02
+* Bug fixes (see mercurial logs for details)
+
+Version 3.6.0 - 2015-04-20
+* Bug fixes (see mercurial logs for details)
+* Add support for PyPy
+Version 3.4.0 - 2014-10-20
+* Bug fixes (see mercurial logs for details)
+
+Version 3.2.0 - 2014-04-21
+* Bug fixes (see mercurial logs for details)
+
+Version 3.0.0 - 2013-10-21
+* Bug fixes (see mercurial logs for details)
+
+Version 2.8.0 - 2013-04-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.6.0 - 2012-10-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.4.0 - 2012-04-24
+* Bug fixes (see mercurial logs for details)
+
+Version 2.2.0 - 2011-10-25
+* Bug fixes (see mercurial logs for details)
+
+Version 2.0.0 - 2011-04-27
+* Bug fixes (see mercurial logs for details)
+
+Version 1.8.0 - 2010-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 1.6.0 - 2010-05-11
+* Bug fixes (see mercurial logs for details)
+
+Version 1.4.0 - 2009-10-19
+* Bug fixes (see mercurial logs for details)
+
+Version 1.2.0 - 2009-07-28
+* Initial release
diff --git a/modules/stock_inventory_location/COPYRIGHT b/modules/stock_inventory_location/COPYRIGHT
new file mode 100644
index 0000000000..df66364561
--- /dev/null
+++ b/modules/stock_inventory_location/COPYRIGHT
@@ -0,0 +1,16 @@
+Copyright (C) 2009-2022 Cédric Krier.
+Copyright (C) 2009-2012 Bertrand Chenal.
+Copyright (C) 2009-2022 B2CK SPRL.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_inventory_location/LICENSE b/modules/stock_inventory_location/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_inventory_location/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_inventory_location/MANIFEST.in b/modules/stock_inventory_location/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_inventory_location/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_inventory_location/README.rst b/modules/stock_inventory_location/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_inventory_location/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_inventory_location/__init__.py b/modules/stock_inventory_location/__init__.py
new file mode 100644
index 0000000000..f6753b9ddc
--- /dev/null
+++ b/modules/stock_inventory_location/__init__.py
@@ -0,0 +1,15 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import inventory
+
+
+def register():
+ Pool.register(
+ inventory.CreateInventoriesStart,
+ module='stock_inventory_location', type_='model')
+ Pool.register(
+ inventory.CreateInventories,
+ module='stock_inventory_location', type_='wizard')
diff --git a/modules/stock_inventory_location/doc/index.rst b/modules/stock_inventory_location/doc/index.rst
new file mode 100644
index 0000000000..df2e925432
--- /dev/null
+++ b/modules/stock_inventory_location/doc/index.rst
@@ -0,0 +1,9 @@
+Stock Inventory Location Module
+###############################
+
+The Stock Inventory Location Module add a new wizard *Create
+Inventories* under the *Inventories* sub-menu.
+
+This wizard first asks the user to select the locations, the products
+and the categories of product that he wants to create inventories for
+and opens them in a new tab.
diff --git a/modules/stock_inventory_location/inventory.py b/modules/stock_inventory_location/inventory.py
new file mode 100644
index 0000000000..792176a607
--- /dev/null
+++ b/modules/stock_inventory_location/inventory.py
@@ -0,0 +1,82 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.model import ModelView, fields
+from trytond.pool import Pool
+from trytond.transaction import Transaction
+from trytond.wizard import Button, StateAction, StateView, Wizard
+
+
+class CreateInventoriesStart(ModelView):
+ 'Create Inventories'
+ __name__ = 'stock.inventory.create.start'
+ date = fields.Date('Date', required=True)
+ company = fields.Many2One('company.company', "Company", required=True)
+ empty_quantity = fields.Selection(
+ 'get_empty_quantities', "Empty Quantity",
+ help="How lines without a quantity are handled.")
+ complete_lines = fields.Boolean(
+ "Complete",
+ help="Add an inventory line for each missing product.")
+ locations = fields.Many2Many('stock.location', None, None,
+ 'Locations', required=True, domain=[('type', '=', 'storage')])
+
+ @classmethod
+ def default_date(cls):
+ return Pool().get('ir.date').today()
+
+ @staticmethod
+ def default_company():
+ return Transaction().context.get('company')
+
+ @classmethod
+ def get_empty_quantities(cls):
+ pool = Pool()
+ Inventory = pool.get('stock.inventory')
+ return Inventory.fields_get(
+ ['empty_quantity'])['empty_quantity']['selection']
+
+ @classmethod
+ def default_empty_quantity(cls):
+ pool = Pool()
+ Inventory = pool.get('stock.inventory')
+ try:
+ return Inventory.default_empty_quantity()
+ except AttributeError:
+ return
+
+ @classmethod
+ def default_complete_lines(cls):
+ return True
+
+
+class CreateInventories(Wizard):
+ 'Create Inventories'
+ __name__ = 'stock.inventory.create'
+ start = StateView('stock.inventory.create.start',
+ 'stock_inventory_location.inventory_create_start_view_form', [
+ Button('Cancel', 'end', 'tryton-cancel'),
+ Button('Create', 'create_', 'tryton-ok', default=True),
+ ])
+ create_ = StateAction('stock.act_inventory_form')
+
+ def get_inventory(self, location, Inventory):
+ return Inventory(
+ location=location,
+ date=self.start.date,
+ company=self.start.company,
+ empty_quantity=self.start.empty_quantity)
+
+ def do_create_(self, action):
+ pool = Pool()
+ Inventory = pool.get('stock.inventory')
+
+ inventories = [
+ self.get_inventory(location, Inventory)
+ for location in self.start.locations]
+ Inventory.save(inventories)
+
+ if self.start.complete_lines:
+ Inventory.complete_lines(inventories)
+
+ data = {'res_id': [i.id for i in inventories]}
+ return action, data
diff --git a/modules/stock_inventory_location/inventory.xml b/modules/stock_inventory_location/inventory.xml
new file mode 100644
index 0000000000..dacadf163c
--- /dev/null
+++ b/modules/stock_inventory_location/inventory.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+ Create Inventories
+ stock.inventory.create
+
+
+
+
+
+
+
+
+
+
+
+
+
+ stock.inventory.create.start
+ form
+ inventory_create_start_form
+
+
+
+ stock.inventory
+
+ inventory_list
+
+
+
diff --git a/modules/stock_inventory_location/locale/bg.po b/modules/stock_inventory_location/locale/bg.po
new file mode 100644
index 0000000000..00c488fa0b
--- /dev/null
+++ b/modules/stock_inventory_location/locale/bg.po
@@ -0,0 +1,53 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Фирма"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "Дата"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr "Местонахождения"
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Създаване на инвентаризация"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "Създаване"
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "Отказ"
diff --git a/modules/stock_inventory_location/locale/ca.po b/modules/stock_inventory_location/locale/ca.po
new file mode 100644
index 0000000000..4a31b0a3e6
--- /dev/null
+++ b/modules/stock_inventory_location/locale/ca.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr "Completa"
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr "Quantitat en blanc"
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr "Ubicacions"
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr "Afegeix una línia d'inventary per a cada producte que falta."
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr "Com es gestionen les línies sense quantitat."
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Crea inventaris"
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Crea inventaris"
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Crea inventaris"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "Crea"
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "Cancel·la"
diff --git a/modules/stock_inventory_location/locale/cs.po b/modules/stock_inventory_location/locale/cs.po
new file mode 100644
index 0000000000..8707e67cf0
--- /dev/null
+++ b/modules/stock_inventory_location/locale/cs.po
@@ -0,0 +1,52 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+#, fuzzy
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr ""
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_inventory_location/locale/de.po b/modules/stock_inventory_location/locale/de.po
new file mode 100644
index 0000000000..8ab0caf561
--- /dev/null
+++ b/modules/stock_inventory_location/locale/de.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Unternehmen"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr "Vervollständigen"
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "Datum"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr "Positionen ohne Erfassung"
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr "Lagerorte"
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr "Inventurposition für jeden fehlenden Artikel hinzufügen."
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr "Bestimmt wie Positionen ohne erfasste Menge behandelt werden."
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Lagerbestände ermitteln"
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Lagerbestände ermitteln"
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Lagerbestände ermitteln"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "Erstellen"
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "Abbrechen"
diff --git a/modules/stock_inventory_location/locale/es.po b/modules/stock_inventory_location/locale/es.po
new file mode 100644
index 0000000000..78ae708154
--- /dev/null
+++ b/modules/stock_inventory_location/locale/es.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr "Completar"
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "Fecha"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr "Cantidad en blanco"
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr "Ubicaciones"
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr "Añade una línea de inventario por cada producto que falta."
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr "Como se gestionan las líneas sin cantidad."
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Crear inventarios"
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Crear inventarios"
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Crear inventarios"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "Crear"
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "Cancelar"
diff --git a/modules/stock_inventory_location/locale/es_419.po b/modules/stock_inventory_location/locale/es_419.po
new file mode 100644
index 0000000000..11656f6b7d
--- /dev/null
+++ b/modules/stock_inventory_location/locale/es_419.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr ""
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr ""
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr ""
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_inventory_location/locale/et.po b/modules/stock_inventory_location/locale/et.po
new file mode 100644
index 0000000000..456834497d
--- /dev/null
+++ b/modules/stock_inventory_location/locale/et.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Ettevõte"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "Kuupäev"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr "Asukohad"
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Loo laoseis"
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Loo laoseis"
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Loo laoseis"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "Loo"
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "Tühista"
diff --git a/modules/stock_inventory_location/locale/fa.po b/modules/stock_inventory_location/locale/fa.po
new file mode 100644
index 0000000000..6219ae670c
--- /dev/null
+++ b/modules/stock_inventory_location/locale/fa.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "شرکت"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "تاریخ"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr "مکان ها"
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "ایجاد فهرست های موجودی"
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "ایجاد فهرست های موجودی"
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "ایجاد فهرست های موجودی"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "ایجاد"
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "انصراف"
diff --git a/modules/stock_inventory_location/locale/fi.po b/modules/stock_inventory_location/locale/fi.po
new file mode 100644
index 0000000000..8707e67cf0
--- /dev/null
+++ b/modules/stock_inventory_location/locale/fi.po
@@ -0,0 +1,52 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+#, fuzzy
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr ""
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_inventory_location/locale/fr.po b/modules/stock_inventory_location/locale/fr.po
new file mode 100644
index 0000000000..a95d7706ed
--- /dev/null
+++ b/modules/stock_inventory_location/locale/fr.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Société"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr "Compléter"
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "Date"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr "Quantité vide"
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr "Emplacements"
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr "Ajouter une ligne d'inventaire pour chaque produit manquant."
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr "Comment les lignes sans quantité sont traitées."
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Créer les inventaires"
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Créer les inventaires"
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Créer des inventaires"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "Créer"
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "Annuler"
diff --git a/modules/stock_inventory_location/locale/hu.po b/modules/stock_inventory_location/locale/hu.po
new file mode 100644
index 0000000000..4097a0d7c8
--- /dev/null
+++ b/modules/stock_inventory_location/locale/hu.po
@@ -0,0 +1,53 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Társaság"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "Dátum"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr "Raktárhely"
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Raktárkészlet meghatározása"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "Létrehozás"
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "Mégse"
diff --git a/modules/stock_inventory_location/locale/id.po b/modules/stock_inventory_location/locale/id.po
new file mode 100644
index 0000000000..4476c8d1b6
--- /dev/null
+++ b/modules/stock_inventory_location/locale/id.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Perusahaan"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "Tanggal"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr ""
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr ""
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "Buat"
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "Batal"
diff --git a/modules/stock_inventory_location/locale/it.po b/modules/stock_inventory_location/locale/it.po
new file mode 100644
index 0000000000..df5bd3404b
--- /dev/null
+++ b/modules/stock_inventory_location/locale/it.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Azienda"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr "Completa"
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr "Quantità vuota"
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr "Posizioni"
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr "Aggiungi una riga di inventario per ogni prodotto mancante."
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr "Come vengono gestite le righe senza una quantità."
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Crea inventari"
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Crea inventari"
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Crea inventari"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "Crea"
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "Annulla"
diff --git a/modules/stock_inventory_location/locale/lo.po b/modules/stock_inventory_location/locale/lo.po
new file mode 100644
index 0000000000..8ef56cc009
--- /dev/null
+++ b/modules/stock_inventory_location/locale/lo.po
@@ -0,0 +1,53 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "ບໍລິສັດ"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "ວັນທີ"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr "ສະຖານທີ່"
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "ສ້າງການກວດນັບ"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "ສ້າງ"
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "ຍົກເລີກ"
diff --git a/modules/stock_inventory_location/locale/lt.po b/modules/stock_inventory_location/locale/lt.po
new file mode 100644
index 0000000000..23d6fc20bf
--- /dev/null
+++ b/modules/stock_inventory_location/locale/lt.po
@@ -0,0 +1,52 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Organizacija"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+#, fuzzy
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr ""
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_inventory_location/locale/nl.po b/modules/stock_inventory_location/locale/nl.po
new file mode 100644
index 0000000000..b6f63ed1c2
--- /dev/null
+++ b/modules/stock_inventory_location/locale/nl.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Bedrijf"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr "Voltooien"
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "datum"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr "Lege hoeveelheid"
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr "locaties"
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr "Voeg een inventarisregel toe voor alle ontbrekende producten."
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr "Hoe lijnen zonder hoeveelheid worden afgehandeld."
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "maak inventaris"
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "maak inventaris"
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "maak inventaris"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "Maken"
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "Annuleren"
diff --git a/modules/stock_inventory_location/locale/pl.po b/modules/stock_inventory_location/locale/pl.po
new file mode 100644
index 0000000000..06b3309cda
--- /dev/null
+++ b/modules/stock_inventory_location/locale/pl.po
@@ -0,0 +1,53 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Firma"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr "Lokalizacje"
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+#, fuzzy
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "Utwórz"
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "Anuluj"
diff --git a/modules/stock_inventory_location/locale/pt.po b/modules/stock_inventory_location/locale/pt.po
new file mode 100644
index 0000000000..69a6ab0e01
--- /dev/null
+++ b/modules/stock_inventory_location/locale/pt.po
@@ -0,0 +1,53 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr "Localizações"
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Criar inventários"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "Criar"
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "Cancelar"
diff --git a/modules/stock_inventory_location/locale/ro.po b/modules/stock_inventory_location/locale/ro.po
new file mode 100644
index 0000000000..052c623886
--- /dev/null
+++ b/modules/stock_inventory_location/locale/ro.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Companie"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr ""
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr ""
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr ""
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_inventory_location/locale/ru.po b/modules/stock_inventory_location/locale/ru.po
new file mode 100644
index 0000000000..8d49a7eff0
--- /dev/null
+++ b/modules/stock_inventory_location/locale/ru.po
@@ -0,0 +1,57 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Учет.орг."
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "Дата"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr "Местоположения"
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+#, fuzzy
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+#, fuzzy
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "Создать"
+
+#, fuzzy
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "Отменить"
diff --git a/modules/stock_inventory_location/locale/sl.po b/modules/stock_inventory_location/locale/sl.po
new file mode 100644
index 0000000000..49c739dd99
--- /dev/null
+++ b/modules/stock_inventory_location/locale/sl.po
@@ -0,0 +1,53 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr "Družba"
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "Datum"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr "Lokacije"
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Izdelava popisov"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr "Izdelaj"
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "Prekliči"
diff --git a/modules/stock_inventory_location/locale/tr.po b/modules/stock_inventory_location/locale/tr.po
new file mode 100644
index 0000000000..8707e67cf0
--- /dev/null
+++ b/modules/stock_inventory_location/locale/tr.po
@@ -0,0 +1,52 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+#, fuzzy
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr ""
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_inventory_location/locale/uk.po b/modules/stock_inventory_location/locale/uk.po
new file mode 100644
index 0000000000..11656f6b7d
--- /dev/null
+++ b/modules/stock_inventory_location/locale/uk.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr ""
+
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr ""
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr ""
+
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_inventory_location/locale/zh_CN.po b/modules/stock_inventory_location/locale/zh_CN.po
new file mode 100644
index 0000000000..17fedbe2ae
--- /dev/null
+++ b/modules/stock_inventory_location/locale/zh_CN.po
@@ -0,0 +1,54 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.inventory.create.start,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,complete_lines:"
+msgid "Complete"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.inventory.create.start,date:"
+msgid "Date"
+msgstr "日期格式"
+
+msgctxt "field:stock.inventory.create.start,empty_quantity:"
+msgid "Empty Quantity"
+msgstr ""
+
+msgctxt "field:stock.inventory.create.start,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,complete_lines:"
+msgid "Add an inventory line for each missing product."
+msgstr ""
+
+msgctxt "help:stock.inventory.create.start,empty_quantity:"
+msgid "How lines without a quantity are handled."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "model:ir.ui.menu,name:menu_create_inventory"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+#, fuzzy
+msgctxt "model:stock.inventory.create.start,name:"
+msgid "Create Inventories"
+msgstr "Create Inventories"
+
+msgctxt "wizard_button:stock.inventory.create,start,create_:"
+msgid "Create"
+msgstr ""
+
+#, fuzzy
+msgctxt "wizard_button:stock.inventory.create,start,end:"
+msgid "Cancel"
+msgstr "取消"
diff --git a/modules/stock_inventory_location/setup.py b/modules/stock_inventory_location/setup.py
new file mode 100755
index 0000000000..ff3ca1ba87
--- /dev/null
+++ b/modules/stock_inventory_location/setup.py
@@ -0,0 +1,152 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_inventory_location'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = []
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [get_require_version('proteus')]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module to create inventories by locations',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": (
+ 'https://hg.tryton.org/modules/stock_inventory_location'),
+ },
+ keywords='tryton inventory location',
+ package_dir={'trytond.modules.stock_inventory_location': '.'},
+ packages=(
+ ['trytond.modules.stock_inventory_location']
+ + ['trytond.modules.stock_inventory_location.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_inventory_location': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'Intended Audience :: Manufacturing',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_inventory_location = trytond.modules.stock_inventory_location
+ """,
+ )
diff --git a/modules/stock_inventory_location/tests/__init__.py b/modules/stock_inventory_location/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_inventory_location/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_inventory_location/tests/scenario_stock_inventories.rst b/modules/stock_inventory_location/tests/scenario_stock_inventories.rst
new file mode 100644
index 0000000000..a8a133d171
--- /dev/null
+++ b/modules/stock_inventory_location/tests/scenario_stock_inventories.rst
@@ -0,0 +1,39 @@
+==========================
+Stock Inventories Scenario
+==========================
+
+Imports::
+
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company
+
+Activate modules::
+
+ >>> config = activate_modules('stock_inventory_location')
+
+Create company::
+
+ >>> _ = create_company()
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+ >>> storage_loc2, = storage_loc.duplicate()
+
+Create inventories::
+
+ >>> create = Wizard('stock.inventory.create')
+ >>> create.form.empty_quantity = 'keep'
+ >>> create.form.locations.extend(Location.find([('code', '=', 'STO')]))
+ >>> create.execute('create_')
+
+ >>> inventories, = create.actions
+ >>> len(inventories)
+ 2
+ >>> {i.location for i in inventories} == {storage_loc, storage_loc2}
+ True
+ >>> inventories[0].empty_quantity
+ 'keep'
diff --git a/modules/stock_inventory_location/tests/test_module.py b/modules/stock_inventory_location/tests/test_module.py
new file mode 100644
index 0000000000..0b6ee2b46a
--- /dev/null
+++ b/modules/stock_inventory_location/tests/test_module.py
@@ -0,0 +1,13 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.modules.company.tests import CompanyTestMixin
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockInventoryLocationTestCase(CompanyTestMixin, ModuleTestCase):
+ 'Test StockInventoryLocation module'
+ module = 'stock_inventory_location'
+
+
+del ModuleTestCase
diff --git a/modules/stock_inventory_location/tests/test_scenario.py b/modules/stock_inventory_location/tests/test_scenario.py
new file mode 100644
index 0000000000..dc1d23e7e5
--- /dev/null
+++ b/modules/stock_inventory_location/tests/test_scenario.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import load_doc_tests
+
+
+def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_inventory_location/tox.ini b/modules/stock_inventory_location/tox.ini
new file mode 100644
index 0000000000..37557d9313
--- /dev/null
+++ b/modules/stock_inventory_location/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_inventory_location/* -m unittest discover -s tests
+ coverage report --include=./**/stock_inventory_location/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_inventory_location/tryton.cfg b/modules/stock_inventory_location/tryton.cfg
new file mode 100644
index 0000000000..30c935ac6f
--- /dev/null
+++ b/modules/stock_inventory_location/tryton.cfg
@@ -0,0 +1,9 @@
+[tryton]
+version=6.7.0
+depends:
+ company
+ ir
+ product
+ stock
+xml:
+ inventory.xml
diff --git a/modules/stock_inventory_location/view/inventory_create_start_form.xml b/modules/stock_inventory_location/view/inventory_create_start_form.xml
new file mode 100644
index 0000000000..5ac5b5b8c7
--- /dev/null
+++ b/modules/stock_inventory_location/view/inventory_create_start_form.xml
@@ -0,0 +1,16 @@
+
+
+
diff --git a/modules/stock_inventory_location/view/inventory_list.xml b/modules/stock_inventory_location/view/inventory_list.xml
new file mode 100644
index 0000000000..768e8dd644
--- /dev/null
+++ b/modules/stock_inventory_location/view/inventory_list.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_location_move/.drone.yml b/modules/stock_location_move/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_location_move/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_location_move/.flake8 b/modules/stock_location_move/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_location_move/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_location_move/.isort.cfg b/modules/stock_location_move/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_location_move/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_location_move/CHANGELOG b/modules/stock_location_move/CHANGELOG
new file mode 100644
index 0000000000..226e4544c8
--- /dev/null
+++ b/modules/stock_location_move/CHANGELOG
@@ -0,0 +1,37 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Initial release
diff --git a/modules/stock_location_move/COPYRIGHT b/modules/stock_location_move/COPYRIGHT
new file mode 100644
index 0000000000..3e3fc46e16
--- /dev/null
+++ b/modules/stock_location_move/COPYRIGHT
@@ -0,0 +1,14 @@
+Copyright (C) 2017-2022 Cédric Krier
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_location_move/LICENSE b/modules/stock_location_move/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_location_move/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_location_move/MANIFEST.in b/modules/stock_location_move/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_location_move/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_location_move/README.rst b/modules/stock_location_move/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_location_move/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_location_move/__init__.py b/modules/stock_location_move/__init__.py
new file mode 100644
index 0000000000..607de67820
--- /dev/null
+++ b/modules/stock_location_move/__init__.py
@@ -0,0 +1,25 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import product, stock
+
+__all__ = ['register']
+
+
+def register():
+ Pool.register(
+ stock.Location,
+ stock.ShipmentInternal,
+ stock.ShipmentInternal_Location,
+ stock.ShipmentOut,
+ stock.ShipmentInReturn,
+ product.Product,
+ module='stock_location_move', type_='model')
+ Pool.register(
+ stock.Supply,
+ module='stock_location_move', type_='wizard',
+ depends=['stock_supply'])
+ Pool.register(
+ module='stock_location_move', type_='report')
diff --git a/modules/stock_location_move/doc/index.rst b/modules/stock_location_move/doc/index.rst
new file mode 100644
index 0000000000..2ec1a68bd1
--- /dev/null
+++ b/modules/stock_location_move/doc/index.rst
@@ -0,0 +1,13 @@
+Stock Location Move Module
+##########################
+
+The stock location move module allows to define some *Locations* as movable
+(like palette).
+
+Such locations can be moved using an *Internal Shipment*. The parent location
+is changed for the destination location when the shipment is done. If there is
+a transit location, the locations will be first moved to this one when shipped.
+A reservation mechanism prevent to assign the same locations at the same time.
+
+If a *Customer Shipment* or a *Supplier Return Shipment* empties a movable
+location, it will automatically deactivate it.
diff --git a/modules/stock_location_move/locale/bg.po b/modules/stock_location_move/locale/bg.po
new file mode 100644
index 0000000000..3edbcf3228
--- /dev/null
+++ b/modules/stock_location_move/locale/bg.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr ""
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Stock Location Movable"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/locale/ca.po b/modules/stock_location_move/locale/ca.po
new file mode 100644
index 0000000000..eca28266d9
--- /dev/null
+++ b/modules/stock_location_move/locale/ca.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr "Reservat per"
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr "Movible"
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr "Ubicacions"
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr "Ubicació"
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr "Albarà"
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr "La ubicació '%(location)s' ja està reservada per '%(assigned_by)s'."
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr "Ubicació movible"
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr "Qualsevol ubicació"
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Ubicacions d'existències movibles"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr "Albarà intern - Ubicació"
diff --git a/modules/stock_location_move/locale/cs.po b/modules/stock_location_move/locale/cs.po
new file mode 100644
index 0000000000..3edbcf3228
--- /dev/null
+++ b/modules/stock_location_move/locale/cs.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr ""
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Stock Location Movable"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/locale/de.po b/modules/stock_location_move/locale/de.po
new file mode 100644
index 0000000000..a6fdd81f7d
--- /dev/null
+++ b/modules/stock_location_move/locale/de.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr "Zugeordnet"
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr "Beweglich"
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr "Lagerorte"
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr "Lagerort"
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr "Lieferung"
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr "Der Lagerort '%(location)s' ist bereits '%(assigned_by)s' zugeordnet."
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr "Mobiler Lagerort"
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr "Beliebiger Lagerort"
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Mobiler Lagerort"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr "Interne Lieferung - Lagerort"
diff --git a/modules/stock_location_move/locale/es.po b/modules/stock_location_move/locale/es.po
new file mode 100644
index 0000000000..609fd062d3
--- /dev/null
+++ b/modules/stock_location_move/locale/es.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr "Reservador por"
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr "Movible"
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr "Ubicaciones"
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr "Ubicación"
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr "Albarán"
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr "La ubicación '%(location)s' ya está reservada por '%(assigned_by)s'."
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr "Ubicación movible"
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr "Cualquier ubicación"
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Ubicaciones de existencias movibles"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr "Albarán interno - Ubicación"
diff --git a/modules/stock_location_move/locale/es_419.po b/modules/stock_location_move/locale/es_419.po
new file mode 100644
index 0000000000..ca763441f2
--- /dev/null
+++ b/modules/stock_location_move/locale/es_419.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr ""
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr ""
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/locale/et.po b/modules/stock_location_move/locale/et.po
new file mode 100644
index 0000000000..66a06609be
--- /dev/null
+++ b/modules/stock_location_move/locale/et.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr "Määratud"
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr "Liigutatav"
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr "Asukohad"
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr "Asukoht"
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr "Lähetus"
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr ""
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/locale/fa.po b/modules/stock_location_move/locale/fa.po
new file mode 100644
index 0000000000..7118ec285d
--- /dev/null
+++ b/modules/stock_location_move/locale/fa.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr "اختصاص داده شده توسط"
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr "قابل جابجایی"
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr "مکان ها"
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr "مکان"
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr "محموله"
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr "مکان : \"%s\" در حال حاضر توسط : \"%s\" اختصاص داده شده است."
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "مکان موجودی قابل جابجایی"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr "مکان - محموله داخلی"
diff --git a/modules/stock_location_move/locale/fi.po b/modules/stock_location_move/locale/fi.po
new file mode 100644
index 0000000000..3edbcf3228
--- /dev/null
+++ b/modules/stock_location_move/locale/fi.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr ""
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Stock Location Movable"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/locale/fr.po b/modules/stock_location_move/locale/fr.po
new file mode 100644
index 0000000000..6f87a4effb
--- /dev/null
+++ b/modules/stock_location_move/locale/fr.po
@@ -0,0 +1,46 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr "Assigné par"
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr "Mobile"
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr "Emplacements"
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr "Emplacement"
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr "Expédition"
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+"L'emplacement « %(location)s » a déjà été assigné par « %(assigned_by)s »."
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr "Emplacement déplaçable"
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr "N'importe quel emplacement"
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Emplacement de stockage déplaçable"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr "Expédition interne - Emplacement"
diff --git a/modules/stock_location_move/locale/hu.po b/modules/stock_location_move/locale/hu.po
new file mode 100644
index 0000000000..3edbcf3228
--- /dev/null
+++ b/modules/stock_location_move/locale/hu.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr ""
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Stock Location Movable"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/locale/id.po b/modules/stock_location_move/locale/id.po
new file mode 100644
index 0000000000..19d3d00db8
--- /dev/null
+++ b/modules/stock_location_move/locale/id.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr ""
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr "Lokasi"
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr ""
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/locale/it.po b/modules/stock_location_move/locale/it.po
new file mode 100644
index 0000000000..883627f980
--- /dev/null
+++ b/modules/stock_location_move/locale/it.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr "Assegnato da"
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr "Mobiliare"
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr "Luoghi"
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr "Luogo"
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr "Spedizione"
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr "Il luogo \"%(location)s\" è già stata assegnata da \"%(assigned_by)s\"."
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr "Luogo mobile"
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr "Qualsiasi luogo"
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Luogo di stock mobiliare"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr "Spedizione interna - Ubicazione"
diff --git a/modules/stock_location_move/locale/lo.po b/modules/stock_location_move/locale/lo.po
new file mode 100644
index 0000000000..3edbcf3228
--- /dev/null
+++ b/modules/stock_location_move/locale/lo.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr ""
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Stock Location Movable"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/locale/lt.po b/modules/stock_location_move/locale/lt.po
new file mode 100644
index 0000000000..3edbcf3228
--- /dev/null
+++ b/modules/stock_location_move/locale/lt.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr ""
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Stock Location Movable"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/locale/nl.po b/modules/stock_location_move/locale/nl.po
new file mode 100644
index 0000000000..fffb67457b
--- /dev/null
+++ b/modules/stock_location_move/locale/nl.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr "Toegekend door"
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr "beweegbaar"
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr "locaties"
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr "locatie"
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr "levering"
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr "De locatie \"%(location)s\" is al toegewezen door \"%(assigned_by)s\"."
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr "Beweegbare locatie"
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr "Elke locatie"
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "voorraad locatie verplaatbaar"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr "Zending intern - Locatie"
diff --git a/modules/stock_location_move/locale/pl.po b/modules/stock_location_move/locale/pl.po
new file mode 100644
index 0000000000..9b219db6ff
--- /dev/null
+++ b/modules/stock_location_move/locale/pl.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr "Przydzielono przez"
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr "Lokalizacje"
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr "Lokalizacja"
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr "Wysyłka"
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Stock Location Movable"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/locale/pt.po b/modules/stock_location_move/locale/pt.po
new file mode 100644
index 0000000000..8bf78ad7b5
--- /dev/null
+++ b/modules/stock_location_move/locale/pt.po
@@ -0,0 +1,47 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr "Atribuído por"
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr "Móvel"
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr "Localizações"
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr "Localização"
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr "Remessa"
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr "A localização '%(location)s' já foi atribuída por '%(assigned_by)s'."
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Stock Location Movable"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr "Remessa Interna - Localização"
diff --git a/modules/stock_location_move/locale/ro.po b/modules/stock_location_move/locale/ro.po
new file mode 100644
index 0000000000..ca763441f2
--- /dev/null
+++ b/modules/stock_location_move/locale/ro.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr ""
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr ""
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/locale/ru.po b/modules/stock_location_move/locale/ru.po
new file mode 100644
index 0000000000..3edbcf3228
--- /dev/null
+++ b/modules/stock_location_move/locale/ru.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr ""
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Stock Location Movable"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/locale/sl.po b/modules/stock_location_move/locale/sl.po
new file mode 100644
index 0000000000..3edbcf3228
--- /dev/null
+++ b/modules/stock_location_move/locale/sl.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr ""
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Stock Location Movable"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/locale/tr.po b/modules/stock_location_move/locale/tr.po
new file mode 100644
index 0000000000..3edbcf3228
--- /dev/null
+++ b/modules/stock_location_move/locale/tr.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr ""
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Stock Location Movable"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/locale/uk.po b/modules/stock_location_move/locale/uk.po
new file mode 100644
index 0000000000..ca763441f2
--- /dev/null
+++ b/modules/stock_location_move/locale/uk.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr ""
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr ""
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/locale/zh_CN.po b/modules/stock_location_move/locale/zh_CN.po
new file mode 100644
index 0000000000..3edbcf3228
--- /dev/null
+++ b/modules/stock_location_move/locale/zh_CN.po
@@ -0,0 +1,45 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,assigned_by:"
+msgid "Assigned by"
+msgstr ""
+
+msgctxt "field:stock.location,movable:"
+msgid "Movable"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.shipment.internal-location,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_location_already_assigned"
+msgid ""
+"The location \"%(location)s\" has already been assigned by "
+"\"%(assigned_by)s\"."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable"
+msgid "Movable location"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_location_movable_admin"
+msgid "Any location"
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_location_movable"
+msgid "Stock Location Movable"
+msgstr "Stock Location Movable"
+
+msgctxt "model:stock.shipment.internal-location,name:"
+msgid "Shipment Internal - Location"
+msgstr ""
diff --git a/modules/stock_location_move/message.xml b/modules/stock_location_move/message.xml
new file mode 100644
index 0000000000..487e44cd54
--- /dev/null
+++ b/modules/stock_location_move/message.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+ The location "%(location)s" has already been assigned by "%(assigned_by)s".
+
+
+
diff --git a/modules/stock_location_move/product.py b/modules/stock_location_move/product.py
new file mode 100644
index 0000000000..86dfd72965
--- /dev/null
+++ b/modules/stock_location_move/product.py
@@ -0,0 +1,24 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import datetime
+
+from trytond.pool import Pool, PoolMeta
+from trytond.transaction import Transaction
+
+
+class Product(metaclass=PoolMeta):
+ __name__ = 'product.product'
+
+ @classmethod
+ def products_by_location(cls, *args, **kwargs):
+ pool = Pool()
+ Location = pool.get('stock.location')
+ context = Transaction().context
+ forecast_location_move = context.get('forecast_location_move', False)
+ if forecast_location_move:
+ date = context.get('stock_date_end') or datetime.date.max
+ restore = Location.forecast_location_move(date)
+ quantities = super(Product, cls).products_by_location(*args, **kwargs)
+ if forecast_location_move:
+ restore()
+ return quantities
diff --git a/modules/stock_location_move/setup.py b/modules/stock_location_move/setup.py
new file mode 100755
index 0000000000..4c79f36de1
--- /dev/null
+++ b/modules/stock_location_move/setup.py
@@ -0,0 +1,151 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_location_move'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = []
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [get_require_version('proteus')]
+for dep in info.get('extras_depend', []):
+ tests_require.append(get_require_version('trytond_%s' % dep))
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module to move storage locations',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_location_move',
+ },
+ keywords='tryton stock location',
+ package_dir={'trytond.modules.stock_location_move': '.'},
+ packages=(
+ ['trytond.modules.stock_location_move']
+ + ['trytond.modules.stock_location_move.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_location_move': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_location_move = trytond.modules.stock_location_move
+ """,
+ )
diff --git a/modules/stock_location_move/stock.py b/modules/stock_location_move/stock.py
new file mode 100644
index 0000000000..baf4718837
--- /dev/null
+++ b/modules/stock_location_move/stock.py
@@ -0,0 +1,267 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import functools
+
+from trytond.i18n import gettext
+from trytond.model import ModelSQL, ModelView, Workflow, fields
+from trytond.modules.stock.exceptions import AssignError
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Eval, If
+from trytond.transaction import Transaction
+
+
+class Location(metaclass=PoolMeta):
+ __name__ = 'stock.location'
+
+ movable = fields.Boolean(
+ "Movable",
+ states={
+ 'invisible': Eval('type') != 'storage',
+ })
+ assigned_by = fields.Reference(
+ "Assigned by", 'get_assigned_by', readonly=True)
+
+ @classmethod
+ def _get_assigned_by(cls):
+ "Return list of Model names for assigned_by Reference"
+ return ['stock.shipment.internal', 'stock.shipment.out']
+
+ @classmethod
+ def get_assigned_by(cls):
+ pool = Pool()
+ IrModel = pool.get('ir.model')
+ get_name = IrModel.get_name
+ models = cls._get_assigned_by()
+ return [(None, '')] + [(m, get_name(m)) for m in models]
+
+ @classmethod
+ def deactivate_empty(cls, locations=None):
+ if locations is None:
+ locations = cls.search([
+ ('movable', '=', True),
+ ])
+ to_deactivate = cls.get_empty_locations(locations)
+ if to_deactivate:
+ cls.write(cls.browse(to_deactivate), {'active': False})
+
+ @classmethod
+ def forecast_location_move(cls, date):
+ """Move temporary locations planned for the date
+ and returns a method to restore the initial parent."""
+ pool = Pool()
+ ShipmentInternal = pool.get('stock.shipment.internal')
+ Location = pool.get('stock.location')
+ Date = pool.get('ir.date')
+
+ today = Date.today()
+ shipments = ShipmentInternal.search([
+ ('locations', '!=', None),
+ ('state', 'not in', ['cancelled', 'done']),
+ ['OR', [
+ ('planned_date', '<=', date),
+ ('planned_date', '>=', today),
+ ('effective_date', '=', None),
+ ], [
+ ('effective_date', '<=', date),
+ ('effective_date', '>=', today),
+ ],
+ ],
+ ],
+ order=[('planned_date', 'ASC'), ('id', 'ASC')])
+ location_parents = {}
+ locations = []
+
+ for shipment in shipments:
+ for location in shipment.locations:
+ location_parents.setdefault(location, location.parent)
+ location.parent = shipment.to_location
+ locations.append(location)
+ Location.save(locations)
+
+ def restore():
+ locations = []
+ for location, parent in location_parents.items():
+ location.parent = parent
+ locations.append(location)
+ Location.save(locations)
+ return restore
+
+
+def clear_location_assignation(func):
+ @functools.wraps(func)
+ def wrapper(cls, shipments, *args, **kwargs):
+ pool = Pool()
+ Location = pool.get('stock.location')
+ locations = []
+ for shipment in shipments:
+ for location in shipment.locations:
+ if location.assigned_by == shipment:
+ locations.append(location)
+ Location.write(locations, {'assigned_by': None})
+ return func(cls, shipments, *args, **kwargs)
+ return wrapper
+
+
+class ShipmentInternal(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.internal'
+
+ locations = fields.Many2Many(
+ 'stock.shipment.internal-location', 'shipment', 'location',
+ "Locations",
+ domain=[
+ ('type', '=', 'storage'),
+ ('movable', '=', True),
+ If(Eval('state') == 'assigned',
+ ('parent', 'child_of', Eval('from_location', -1)),
+ ()),
+ ],
+ states={
+ 'readonly': (~Eval('state').in_(['request', 'draft'])
+ | ~Eval('from_location') | ~Eval('to_location')),
+ })
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('draft')
+ @clear_location_assignation
+ def draft(cls, shipments):
+ super(ShipmentInternal, cls).draft(shipments)
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('waiting')
+ @clear_location_assignation
+ def wait(cls, shipments):
+ super(ShipmentInternal, cls).wait(shipments)
+
+ @classmethod
+ @Workflow.transition('assigned')
+ def assign(cls, shipments):
+ pool = Pool()
+ Location = pool.get('stock.location')
+ locations = {}
+ for shipment in shipments:
+ for location in shipment.locations:
+ if not location.assigned_by:
+ location.assigned_by = shipment
+ if location in locations:
+ raise AssignError(
+ gettext('stock_location_move'
+ '.msg_location_already_assigned') % {
+ 'location': location.rec_name,
+ 'assigned_by': locations[location].rec_name,
+ })
+ locations[location] = location.assigned_by
+ elif location.assigned_by != shipment:
+ raise AssignError(
+ gettext('stock_location_move'
+ '.msg_location_already_assigned') % {
+ 'location': location.rec_name,
+ 'assigned_by': location.assigned_by.rec_name,
+ })
+ if locations:
+ Location.save(list(locations))
+ super(ShipmentInternal, cls).assign(shipments)
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('shipped')
+ def ship(cls, shipments):
+ pool = Pool()
+ Location = pool.get('stock.location')
+ to_write = []
+ for shipment in shipments:
+ if not shipment.transit_location or not shipment.locations:
+ continue
+ to_write.append(list(shipment.locations))
+ to_write.append({
+ 'parent': shipment.transit_location.id,
+ })
+ if to_write:
+ Location.write(*to_write)
+ super(ShipmentInternal, cls).ship(shipments)
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('done')
+ @clear_location_assignation
+ def done(cls, shipments):
+ pool = Pool()
+ Location = pool.get('stock.location')
+ to_write = []
+ for shipment in shipments:
+ if not shipment.locations:
+ continue
+ to_write.append(list(shipment.locations))
+ to_write.append({
+ 'parent': shipment.to_location.id,
+ })
+ if to_write:
+ Location.write(*to_write)
+ super(ShipmentInternal, cls).done(shipments)
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('cancelled')
+ @clear_location_assignation
+ def cancel(cls, shipments):
+ super(ShipmentInternal, cls).cancel(shipments)
+
+
+class ShipmentInternal_Location(ModelSQL):
+ "Shipment Internal - Location"
+ __name__ = 'stock.shipment.internal-location'
+
+ shipment = fields.Many2One(
+ 'stock.shipment.internal', "Shipment", required=True)
+ location = fields.Many2One(
+ 'stock.location', "Location", required=True,
+ domain=[
+ ('type', '=', 'storage'),
+ ('movable', '=', True),
+ ])
+
+
+def deactivate_empty_location(func):
+ @functools.wraps(func)
+ def wrapper(cls, shipments, *args, **kwargs):
+ pool = Pool()
+ Location = pool.get('stock.location')
+ func(cls, shipments, *args, **kwargs)
+ locations = set()
+ for shipment in shipments:
+ locations.update(
+ move.from_location for move in shipment.moves
+ if move.from_location.movable)
+ Location.deactivate_empty(list(locations))
+ return wrapper
+
+
+class ShipmentOut(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out'
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('done')
+ @deactivate_empty_location
+ def done(cls, shipments):
+ super(ShipmentOut, cls).done(shipments)
+
+
+class ShipmentInReturn(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in.return'
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('done')
+ @deactivate_empty_location
+ def done(cls, shipments):
+ super(ShipmentInReturn, cls).done(shipments)
+
+
+class Supply(metaclass=PoolMeta):
+ __name__ = 'stock.supply'
+
+ def transition_create_(self):
+ with Transaction().set_context(forecast_location_move=True):
+ return super(Supply, self).transition_create_()
diff --git a/modules/stock_location_move/stock.xml b/modules/stock_location_move/stock.xml
new file mode 100644
index 0000000000..37c2af6397
--- /dev/null
+++ b/modules/stock_location_move/stock.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+ Stock Location Movable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Movable location
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Any location
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ stock.location
+
+ location_form
+
+
+
+ stock.shipment.internal
+
+ shipment_internal_form
+
+
+
diff --git a/modules/stock_location_move/tests/__init__.py b/modules/stock_location_move/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_location_move/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_location_move/tests/scenario_stock_location_move.rst b/modules/stock_location_move/tests/scenario_stock_location_move.rst
new file mode 100644
index 0000000000..7e3adbd6bb
--- /dev/null
+++ b/modules/stock_location_move/tests/scenario_stock_location_move.rst
@@ -0,0 +1,130 @@
+============================
+Stock Location Move Scenario
+============================
+
+Imports::
+
+ >>> import datetime
+
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> today = datetime.date.today()
+ >>> tomorrow = today + datetime.timedelta(1)
+
+Activate modules::
+
+ >>> config = activate_modules('stock_location_move')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+ >>> storage1 = Location(name="Storage 1", parent=storage_loc)
+ >>> storage1.save()
+ >>> storage2 = Location(name="Storage 2", parent=storage_loc)
+ >>> storage2.save()
+ >>> pallet = Location(name="Pallet", parent=storage1, movable=True)
+ >>> pallet.save()
+
+Move pallet from storage1 to storage2::
+
+ >>> Shipment = Model.get('stock.shipment.internal')
+ >>> shipment = Shipment()
+ >>> shipment.from_location = storage1
+ >>> shipment.to_location = storage2
+ >>> shipment.locations.append(Location(pallet.id))
+ >>> shipment.click('wait')
+
+ >>> shipment.click('assign_try')
+ True
+ >>> shipment.state
+ 'assigned'
+ >>> pallet.reload()
+ >>> pallet.assigned_by == shipment
+ True
+ >>> pallet.parent == storage1
+ True
+
+ >>> shipment.click('done')
+ >>> shipment.state
+ 'done'
+ >>> pallet.reload()
+ >>> pallet.assigned_by
+ >>> pallet.parent == storage2
+ True
+
+Assign pallet from wrong location::
+
+ >>> shipment = Shipment()
+ >>> shipment.from_location = storage1
+ >>> shipment.to_location = storage2
+ >>> shipment.locations.append(Location(pallet.id))
+ >>> shipment.click('wait')
+ >>> shipment.click('assign_try') # doctest: +IGNORE_EXCEPTION_DETAIL
+ Traceback (most recent call last):
+ ...
+ DomainValidationError: ...
+
+Concurrently move pallet::
+
+ >>> shipment1 = Shipment()
+ >>> shipment1.from_location = storage2
+ >>> shipment1.to_location = storage1
+ >>> shipment1.locations.append(Location(pallet.id))
+ >>> shipment1.click('wait')
+
+ >>> shipment2 = Shipment()
+ >>> shipment2.from_location = storage2
+ >>> shipment2.to_location = storage1
+ >>> shipment2.locations.append(Location(pallet.id))
+ >>> shipment2.click('wait')
+
+ >>> shipment1.click('assign_try')
+ True
+ >>> shipment2.click('assign_try') # doctest: +IGNORE_EXCEPTION_DETAIL
+ Traceback (most recent call last):
+ ...
+ AssignError: ...
+
+ >>> shipment1.click('done')
+
+Add lead time between warehouses::
+
+ >>> warehouse1 = storage_loc.warehouse
+ >>> warehouse2, = warehouse1.duplicate()
+
+ >>> LeadTime = Model.get('stock.location.lead_time')
+ >>> lead_time = LeadTime()
+ >>> lead_time.warehouse_from = warehouse1
+ >>> lead_time.warehouse_to = warehouse2
+ >>> lead_time.lead_time = datetime.timedelta(1)
+ >>> lead_time.save()
+
+Move pallet from storage1 to storage2 with lead_time::
+
+ >>> Shipment = Model.get('stock.shipment.internal')
+ >>> shipment = Shipment()
+ >>> shipment.planned_date = tomorrow
+ >>> shipment.from_location = warehouse1.storage_location
+ >>> shipment.to_location = warehouse2.storage_location
+ >>> shipment.locations.append(Location(pallet.id))
+ >>> shipment.click('wait')
+ >>> shipment.click('assign_try')
+ True
+
+ >>> shipment.click('ship')
+ >>> pallet.reload()
+ >>> pallet.parent == shipment.transit_location
+ True
+
+ >>> shipment.click('done')
+ >>> pallet.reload()
+ >>> pallet.parent == warehouse2.storage_location
+ True
diff --git a/modules/stock_location_move/tests/scenario_stock_location_move_empty.rst b/modules/stock_location_move/tests/scenario_stock_location_move_empty.rst
new file mode 100644
index 0000000000..128cd4c3d7
--- /dev/null
+++ b/modules/stock_location_move/tests/scenario_stock_location_move_empty.rst
@@ -0,0 +1,162 @@
+==================================
+Stock Location Move Empty Scenario
+==================================
+
+Imports::
+
+ >>> import datetime
+ >>> from decimal import Decimal
+
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> today = datetime.date.today()
+ >>> yesterday = today - datetime.timedelta(1)
+ >>> tomorrow = today + datetime.timedelta(1)
+
+Activate modules::
+
+ >>> config = activate_modules('stock_location_move')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create customer::
+
+ >>> Party = Model.get('party.party')
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+ >>> storage1 = Location(name="Storage 1", parent=storage_loc)
+ >>> storage1.save()
+ >>> pallet1 = Location(name="Pallet 1", parent=storage_loc, movable=True)
+ >>> pallet1.save()
+ >>> pallet2 = Location(name="Pallet 2", parent=storage_loc, movable=True)
+ >>> pallet2.save()
+ >>> pallet3 = Location(name="Pallet 3", parent=storage_loc, movable=True)
+ >>> pallet3.save()
+
+Create products::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> Product = Model.get('product.product')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal(0)
+ >>> template.save()
+ >>> product1 = Product()
+ >>> product1.template = template
+ >>> product1.save()
+ >>> product2 = Product()
+ >>> product2.template = template
+ >>> product2.save()
+ >>> product3 = Product()
+ >>> product3.template = template
+ >>> product3.save()
+
+Fill storage locations::
+
+ >>> StockMove = Model.get('stock.move')
+
+ >>> incoming_move = StockMove()
+ >>> incoming_move.product = product1
+ >>> incoming_move.quantity = 1
+ >>> incoming_move.unit_price = Decimal('0')
+ >>> incoming_move.currency = company.currency
+ >>> incoming_move.from_location = supplier_loc
+ >>> incoming_move.to_location = storage1
+ >>> incoming_move.effective_date = yesterday
+ >>> incoming_move.click('do')
+
+ >>> incoming_move = StockMove()
+ >>> incoming_move.product = product2
+ >>> incoming_move.quantity = 1
+ >>> incoming_move.unit_price = Decimal('0')
+ >>> incoming_move.currency = company.currency
+ >>> incoming_move.from_location = supplier_loc
+ >>> incoming_move.to_location = pallet1
+ >>> incoming_move.effective_date = yesterday
+ >>> incoming_move.click('do')
+
+ >>> incoming_move = StockMove()
+ >>> incoming_move.product = product3
+ >>> incoming_move.quantity = 2
+ >>> incoming_move.unit_price = Decimal('0')
+ >>> incoming_move.currency = company.currency
+ >>> incoming_move.from_location = supplier_loc
+ >>> incoming_move.to_location = pallet2
+ >>> incoming_move.effective_date = yesterday
+ >>> incoming_move.click('do')
+
+Ship 1 product from the locations::
+
+ >>> ShipmentOut = Model.get('stock.shipment.out')
+ >>> shipment = ShipmentOut()
+ >>> shipment.customer = customer
+ >>> shipment.warehouse = warehouse_loc
+ >>> move = shipment.outgoing_moves.new()
+ >>> move.product = product1
+ >>> move.quantity = 1
+ >>> move.unit_price = Decimal('0')
+ >>> move.currency = company.currency
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> move = shipment.outgoing_moves.new()
+ >>> move.product = product2
+ >>> move.quantity = 1
+ >>> move.unit_price = Decimal('0')
+ >>> move.currency = company.currency
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> move = shipment.outgoing_moves.new()
+ >>> move.product = product3
+ >>> move.quantity = 1
+ >>> move.unit_price = Decimal('0')
+ >>> move.currency = company.currency
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> shipment.click('wait')
+ >>> shipment.click('assign_try')
+ True
+ >>> shipment.click('pick')
+ >>> shipment.click('pack')
+ >>> shipment.click('done')
+
+Check empty non movable location are still active::
+
+ >>> storage1.reload()
+ >>> bool(storage1.active)
+ True
+
+Check empty location are deactivated::
+
+ >>> pallet1.reload()
+ >>> bool(pallet1.active)
+ False
+
+Check non empty location are still active::
+
+ >>> pallet2.reload()
+ >>> bool(pallet2.active)
+ True
+
+Check non changed empty location are still active::
+
+ >>> pallet3.reload()
+ >>> bool(pallet3.active)
+ True
diff --git a/modules/stock_location_move/tests/scenario_stock_location_move_supply.rst b/modules/stock_location_move/tests/scenario_stock_location_move_supply.rst
new file mode 100644
index 0000000000..a5ec42803c
--- /dev/null
+++ b/modules/stock_location_move/tests/scenario_stock_location_move_supply.rst
@@ -0,0 +1,111 @@
+==========================
+Stock Location Move Supply
+==========================
+
+Imports::
+
+ >>> import datetime
+ >>> from decimal import Decimal
+
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> today = datetime.date.today()
+
+Activate modules::
+
+ >>> config = activate_modules(['stock_location_move', 'stock_supply'])
+
+Create customer::
+
+ >>> Party = Model.get('party.party')
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+ >>> provisioning_loc = Location(
+ ... name="Provisioning Location", parent=warehouse_loc)
+ >>> provisioning_loc.save()
+ >>> pallet = Location(name="Pallet", parent=provisioning_loc, movable=True)
+ >>> pallet.save()
+
+Create products::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> Product = Model.get('product.product')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal(0)
+ >>> template.save()
+ >>> product = Product()
+ >>> product.template = template
+ >>> product.save()
+
+Create internal order point::
+
+ >>> OrderPoint = Model.get('stock.order_point')
+ >>> order_point = OrderPoint()
+ >>> order_point.product = product
+ >>> order_point.storage_location = storage_loc
+ >>> order_point.provisioning_location = provisioning_loc
+ >>> order_point.type = 'internal'
+ >>> order_point.min_quantity = 2
+ >>> order_point.target_quantity = 2
+ >>> order_point.save()
+
+Fill pallet::
+
+ >>> Inventory = Model.get('stock.inventory')
+ >>> inventory = Inventory()
+ >>> inventory.location = pallet
+ >>> inventory_line = inventory.lines.new(product=product)
+ >>> inventory_line.quantity = 1
+ >>> inventory.click('confirm')
+
+Plan moving pallet::
+
+ >>> ShipmentInternal = Model.get('stock.shipment.internal')
+ >>> shipment = ShipmentInternal()
+ >>> shipment.planned_date = today
+ >>> shipment.from_location = provisioning_loc
+ >>> shipment.to_location = storage_loc
+ >>> shipment.locations.append(Location(pallet.id))
+ >>> shipment.save()
+
+Execute internal supply::
+
+ >>> Wizard('stock.supply').execute('create_')
+
+Only 1 product is requested::
+
+ >>> shipment, = ShipmentInternal.find([
+ ... ('id', '!=', shipment.id),
+ ... ])
+ >>> shipment.state
+ 'request'
+ >>> move, = shipment.moves
+ >>> move.quantity
+ 1.0
+
+Pallet did not moved::
+
+ >>> pallet.reload()
+ >>> pallet.parent.name
+ 'Provisioning Location'
diff --git a/modules/stock_location_move/tests/test_module.py b/modules/stock_location_move/tests/test_module.py
new file mode 100644
index 0000000000..07d83b344e
--- /dev/null
+++ b/modules/stock_location_move/tests/test_module.py
@@ -0,0 +1,13 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockLocationMoveTestCase(ModuleTestCase):
+ 'Test Stock Location Move module'
+ module = 'stock_location_move'
+ extras = ['stock_supply']
+
+
+del ModuleTestCase
diff --git a/modules/stock_location_move/tests/test_scenario.py b/modules/stock_location_move/tests/test_scenario.py
new file mode 100644
index 0000000000..dc1d23e7e5
--- /dev/null
+++ b/modules/stock_location_move/tests/test_scenario.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import load_doc_tests
+
+
+def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_location_move/tox.ini b/modules/stock_location_move/tox.ini
new file mode 100644
index 0000000000..31f227721f
--- /dev/null
+++ b/modules/stock_location_move/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_location_move/* -m unittest discover -s tests
+ coverage report --include=./**/stock_location_move/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_location_move/tryton.cfg b/modules/stock_location_move/tryton.cfg
new file mode 100644
index 0000000000..2841dcfc21
--- /dev/null
+++ b/modules/stock_location_move/tryton.cfg
@@ -0,0 +1,10 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ stock
+extras_depend:
+ stock_supply
+xml:
+ stock.xml
+ message.xml
diff --git a/modules/stock_location_move/view/location_form.xml b/modules/stock_location_move/view/location_form.xml
new file mode 100644
index 0000000000..c4105b2e65
--- /dev/null
+++ b/modules/stock_location_move/view/location_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_location_move/view/shipment_internal_form.xml b/modules/stock_location_move/view/shipment_internal_form.xml
new file mode 100644
index 0000000000..baf5458182
--- /dev/null
+++ b/modules/stock_location_move/view/shipment_internal_form.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_location_sequence/.drone.yml b/modules/stock_location_sequence/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_location_sequence/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_location_sequence/.flake8 b/modules/stock_location_sequence/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_location_sequence/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_location_sequence/.isort.cfg b/modules/stock_location_sequence/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_location_sequence/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_location_sequence/CHANGELOG b/modules/stock_location_sequence/CHANGELOG
new file mode 100644
index 0000000000..cb4a43cc28
--- /dev/null
+++ b/modules/stock_location_sequence/CHANGELOG
@@ -0,0 +1,89 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+
+Version 4.2.0 - 2016-11-28
+* Bug fixes (see mercurial logs for details)
+
+Version 4.0.0 - 2016-05-02
+* Bug fixes (see mercurial logs for details)
+* Add Python3 support
+
+Version 3.8.0 - 2015-11-02
+* Bug fixes (see mercurial logs for details)
+
+Version 3.6.0 - 2015-04-20
+* Bug fixes (see mercurial logs for details)
+* Add support for PyPy
+Version 3.4.0 - 2014-10-20
+* Bug fixes (see mercurial logs for details)
+
+Version 3.2.0 - 2014-04-21
+* Bug fixes (see mercurial logs for details)
+
+Version 3.0.0 - 2013-10-21
+* Bug fixes (see mercurial logs for details)
+
+Version 2.8.0 - 2013-04-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.6.0 - 2012-10-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.4.0 - 2012-04-24
+* Bug fixes (see mercurial logs for details)
+
+Version 2.2.0 - 2011-10-25
+* Bug fixes (see mercurial logs for details)
+
+Version 2.0.0 - 2011-04-27
+* Bug fixes (see mercurial logs for details)
+
+Version 1.8.0 - 2010-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 1.6.0 - 2010-05-12
+* Bug fixes (see mercurial logs for details)
+
+Version 1.4.0 - 2009-10-19
+* Bug fixes (see mercurial logs for details)
+
+Version 1.2.0 - 2009-04-20
+* Initial release
diff --git a/modules/stock_location_sequence/COPYRIGHT b/modules/stock_location_sequence/COPYRIGHT
new file mode 100644
index 0000000000..068e2b6331
--- /dev/null
+++ b/modules/stock_location_sequence/COPYRIGHT
@@ -0,0 +1,16 @@
+Copyright (C) 2008-2022 Cédric Krier.
+Copyright (C) 2008-2012 Bertrand Chenal.
+Copyright (C) 2008-2022 B2CK SPRL.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_location_sequence/LICENSE b/modules/stock_location_sequence/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_location_sequence/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_location_sequence/MANIFEST.in b/modules/stock_location_sequence/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_location_sequence/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_location_sequence/README.rst b/modules/stock_location_sequence/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_location_sequence/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_location_sequence/__init__.py b/modules/stock_location_sequence/__init__.py
new file mode 100644
index 0000000000..edaacbf806
--- /dev/null
+++ b/modules/stock_location_sequence/__init__.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import stock
+
+
+def register():
+ Pool.register(
+ stock.Location,
+ module='stock_location_sequence', type_='model')
diff --git a/modules/stock_location_sequence/doc/index.rst b/modules/stock_location_sequence/doc/index.rst
new file mode 100644
index 0000000000..73372bfb77
--- /dev/null
+++ b/modules/stock_location_sequence/doc/index.rst
@@ -0,0 +1,4 @@
+Stock Location Sequence Module
+##############################
+
+The stock location sequence module adds ordering to location.
diff --git a/modules/stock_location_sequence/locale/bg.po b/modules/stock_location_sequence/locale/bg.po
new file mode 100644
index 0000000000..6b4a36f8d9
--- /dev/null
+++ b/modules/stock_location_sequence/locale/bg.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Последователност"
diff --git a/modules/stock_location_sequence/locale/ca.po b/modules/stock_location_sequence/locale/ca.po
new file mode 100644
index 0000000000..dc825b67bb
--- /dev/null
+++ b/modules/stock_location_sequence/locale/ca.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Seqüència"
diff --git a/modules/stock_location_sequence/locale/cs.po b/modules/stock_location_sequence/locale/cs.po
new file mode 100644
index 0000000000..f0ab631935
--- /dev/null
+++ b/modules/stock_location_sequence/locale/cs.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr ""
diff --git a/modules/stock_location_sequence/locale/de.po b/modules/stock_location_sequence/locale/de.po
new file mode 100644
index 0000000000..a648250dbd
--- /dev/null
+++ b/modules/stock_location_sequence/locale/de.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Reihenfolge"
diff --git a/modules/stock_location_sequence/locale/es.po b/modules/stock_location_sequence/locale/es.po
new file mode 100644
index 0000000000..6056d4dfb3
--- /dev/null
+++ b/modules/stock_location_sequence/locale/es.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Secuencia"
diff --git a/modules/stock_location_sequence/locale/es_419.po b/modules/stock_location_sequence/locale/es_419.po
new file mode 100644
index 0000000000..f0ab631935
--- /dev/null
+++ b/modules/stock_location_sequence/locale/es_419.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr ""
diff --git a/modules/stock_location_sequence/locale/et.po b/modules/stock_location_sequence/locale/et.po
new file mode 100644
index 0000000000..82b9214fb9
--- /dev/null
+++ b/modules/stock_location_sequence/locale/et.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Järjestus"
diff --git a/modules/stock_location_sequence/locale/fa.po b/modules/stock_location_sequence/locale/fa.po
new file mode 100644
index 0000000000..f23264517d
--- /dev/null
+++ b/modules/stock_location_sequence/locale/fa.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "ادامه"
diff --git a/modules/stock_location_sequence/locale/fi.po b/modules/stock_location_sequence/locale/fi.po
new file mode 100644
index 0000000000..f0ab631935
--- /dev/null
+++ b/modules/stock_location_sequence/locale/fi.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr ""
diff --git a/modules/stock_location_sequence/locale/fr.po b/modules/stock_location_sequence/locale/fr.po
new file mode 100644
index 0000000000..fca827bcef
--- /dev/null
+++ b/modules/stock_location_sequence/locale/fr.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Séquence"
diff --git a/modules/stock_location_sequence/locale/hu.po b/modules/stock_location_sequence/locale/hu.po
new file mode 100644
index 0000000000..b47ea95bc7
--- /dev/null
+++ b/modules/stock_location_sequence/locale/hu.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Sorrend"
diff --git a/modules/stock_location_sequence/locale/id.po b/modules/stock_location_sequence/locale/id.po
new file mode 100644
index 0000000000..34e2e7a197
--- /dev/null
+++ b/modules/stock_location_sequence/locale/id.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Urutan"
diff --git a/modules/stock_location_sequence/locale/it.po b/modules/stock_location_sequence/locale/it.po
new file mode 100644
index 0000000000..5947eebb59
--- /dev/null
+++ b/modules/stock_location_sequence/locale/it.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Sequenza"
diff --git a/modules/stock_location_sequence/locale/lo.po b/modules/stock_location_sequence/locale/lo.po
new file mode 100644
index 0000000000..15dcc80f03
--- /dev/null
+++ b/modules/stock_location_sequence/locale/lo.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "ລໍາດັບ"
diff --git a/modules/stock_location_sequence/locale/lt.po b/modules/stock_location_sequence/locale/lt.po
new file mode 100644
index 0000000000..f0ab631935
--- /dev/null
+++ b/modules/stock_location_sequence/locale/lt.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr ""
diff --git a/modules/stock_location_sequence/locale/nl.po b/modules/stock_location_sequence/locale/nl.po
new file mode 100644
index 0000000000..64b692f28f
--- /dev/null
+++ b/modules/stock_location_sequence/locale/nl.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Reeks"
diff --git a/modules/stock_location_sequence/locale/pl.po b/modules/stock_location_sequence/locale/pl.po
new file mode 100644
index 0000000000..2a81c5afca
--- /dev/null
+++ b/modules/stock_location_sequence/locale/pl.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Kolejność"
diff --git a/modules/stock_location_sequence/locale/pt.po b/modules/stock_location_sequence/locale/pt.po
new file mode 100644
index 0000000000..6c22676c16
--- /dev/null
+++ b/modules/stock_location_sequence/locale/pt.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Sequência"
diff --git a/modules/stock_location_sequence/locale/ro.po b/modules/stock_location_sequence/locale/ro.po
new file mode 100644
index 0000000000..6dbade116b
--- /dev/null
+++ b/modules/stock_location_sequence/locale/ro.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Secvenţă"
diff --git a/modules/stock_location_sequence/locale/ru.po b/modules/stock_location_sequence/locale/ru.po
new file mode 100644
index 0000000000..e977e853c6
--- /dev/null
+++ b/modules/stock_location_sequence/locale/ru.po
@@ -0,0 +1,8 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Последовательность"
diff --git a/modules/stock_location_sequence/locale/sl.po b/modules/stock_location_sequence/locale/sl.po
new file mode 100644
index 0000000000..b62c60e11c
--- /dev/null
+++ b/modules/stock_location_sequence/locale/sl.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Zap.št."
diff --git a/modules/stock_location_sequence/locale/tr.po b/modules/stock_location_sequence/locale/tr.po
new file mode 100644
index 0000000000..478a3db38b
--- /dev/null
+++ b/modules/stock_location_sequence/locale/tr.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "Sıra"
diff --git a/modules/stock_location_sequence/locale/uk.po b/modules/stock_location_sequence/locale/uk.po
new file mode 100644
index 0000000000..f0ab631935
--- /dev/null
+++ b/modules/stock_location_sequence/locale/uk.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr ""
diff --git a/modules/stock_location_sequence/locale/zh_CN.po b/modules/stock_location_sequence/locale/zh_CN.po
new file mode 100644
index 0000000000..798af85267
--- /dev/null
+++ b/modules/stock_location_sequence/locale/zh_CN.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.location,sequence:"
+msgid "Sequence"
+msgstr "序列"
diff --git a/modules/stock_location_sequence/setup.py b/modules/stock_location_sequence/setup.py
new file mode 100755
index 0000000000..612f16f17b
--- /dev/null
+++ b/modules/stock_location_sequence/setup.py
@@ -0,0 +1,147 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_location_sequence'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = ['python-sql >= 0.4']
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module to add sequence on location',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_location_sequence',
+ },
+ keywords='tryton stock location sequence',
+ package_dir={'trytond.modules.stock_location_sequence': '.'},
+ packages=(
+ ['trytond.modules.stock_location_sequence']
+ + ['trytond.modules.stock_location_sequence.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_location_sequence': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'Intended Audience :: Manufacturing',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_location_sequence = trytond.modules.stock_location_sequence
+ """,
+ )
diff --git a/modules/stock_location_sequence/stock.py b/modules/stock_location_sequence/stock.py
new file mode 100644
index 0000000000..08184678da
--- /dev/null
+++ b/modules/stock_location_sequence/stock.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.model import sequence_ordered
+from trytond.pool import PoolMeta
+
+
+class Location(sequence_ordered(), metaclass=PoolMeta):
+ __name__ = 'stock.location'
diff --git a/modules/stock_location_sequence/stock.xml b/modules/stock_location_sequence/stock.xml
new file mode 100644
index 0000000000..3cea5849e5
--- /dev/null
+++ b/modules/stock_location_sequence/stock.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+ stock.location
+
+
+ location_form
+
+
+
diff --git a/modules/stock_location_sequence/tests/__init__.py b/modules/stock_location_sequence/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_location_sequence/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_location_sequence/tests/test_module.py b/modules/stock_location_sequence/tests/test_module.py
new file mode 100644
index 0000000000..d901cd7560
--- /dev/null
+++ b/modules/stock_location_sequence/tests/test_module.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockLocationSequenceTestCase(ModuleTestCase):
+ 'Test StockLocationSequence module'
+ module = 'stock_location_sequence'
+
+
+del ModuleTestCase
diff --git a/modules/stock_location_sequence/tox.ini b/modules/stock_location_sequence/tox.ini
new file mode 100644
index 0000000000..189eabf611
--- /dev/null
+++ b/modules/stock_location_sequence/tox.ini
@@ -0,0 +1,16 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+commands =
+ coverage run --include=./**/stock_location_sequence/* -m unittest discover -s tests
+ coverage report --include=./**/stock_location_sequence/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_location_sequence/tryton.cfg b/modules/stock_location_sequence/tryton.cfg
new file mode 100644
index 0000000000..ec73702285
--- /dev/null
+++ b/modules/stock_location_sequence/tryton.cfg
@@ -0,0 +1,7 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ stock
+xml:
+ stock.xml
diff --git a/modules/stock_location_sequence/view/location_form.xml b/modules/stock_location_sequence/view/location_form.xml
new file mode 100644
index 0000000000..d1faf82d9a
--- /dev/null
+++ b/modules/stock_location_sequence/view/location_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot/.drone.yml b/modules/stock_lot/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_lot/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_lot/.flake8 b/modules/stock_lot/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_lot/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_lot/.isort.cfg b/modules/stock_lot/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_lot/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_lot/CHANGELOG b/modules/stock_lot/CHANGELOG
new file mode 100644
index 0000000000..e18a172206
--- /dev/null
+++ b/modules/stock_lot/CHANGELOG
@@ -0,0 +1,89 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Synchronize lot on drop shipment
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add lot to assign criteria if not empty
+* Add lot traceability
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+* Add wizard to add lots
+* Allow lot sequence number to be configured on product
+* Add lots_by_locations Model
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+* Add relate to locations quantity
+* Add lots by warehouse relate
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+* Use MultiSelection for lot_required
+* Synchronize lot on internal shipment
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Allow to count inventory by lot
+* Remove support for Python 2.7
+* Check no move when modify product of lot
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+
+Version 4.2.0 - 2016-11-28
+* Bug fixes (see mercurial logs for details)
+* Add entry to show lot quantities
+
+Version 4.0.0 - 2016-05-02
+* Bug fixes (see mercurial logs for details)
+* Add Python3 support
+
+Version 3.8.0 - 2015-11-02
+* Bug fixes (see mercurial logs for details)
+* Adapt inventory to use grouping
+
+Version 3.6.0 - 2015-04-20
+* Bug fixes (see mercurial logs for details)
+* Add support for PyPy
+Version 3.4.0 - 2014-10-20
+* Bug fixes (see mercurial logs for details)
+
+Version 3.2.0 - 2014-04-21
+* Bug fixes (see mercurial logs for details)
+* Add relate from lot to moves
+
+Version 3.0.0 - 2013-10-21
+* Bug fixes (see mercurial logs for details)
+* Add quantity and forecast_quantity fields on Lot
+* Add lot in inventory
+* Add Period Cache per lot
+
+Version 2.8.0 - 2013-04-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.6.0 - 2012-10-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.4.0 - 2012-07-31
+* Initial release
diff --git a/modules/stock_lot/COPYRIGHT b/modules/stock_lot/COPYRIGHT
new file mode 100644
index 0000000000..03f4719f79
--- /dev/null
+++ b/modules/stock_lot/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2012-2022 Cédric Krier.
+Copyright (C) 2012-2022 B2CK SPRL.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_lot/LICENSE b/modules/stock_lot/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_lot/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_lot/MANIFEST.in b/modules/stock_lot/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_lot/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_lot/README.rst b/modules/stock_lot/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_lot/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_lot/__init__.py b/modules/stock_lot/__init__.py
new file mode 100644
index 0000000000..2021916f1e
--- /dev/null
+++ b/modules/stock_lot/__init__.py
@@ -0,0 +1,44 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import product, stock
+from .stock import LotMixin
+
+__all__ = ['LotMixin', 'register']
+
+
+def register():
+ Pool.register(
+ stock.Lot,
+ stock.LotTrace,
+ stock.LotByLocationContext,
+ stock.LotsByLocations,
+ stock.LotByWarehouseContext,
+ stock.Location,
+ stock.Move,
+ stock.MoveAddLotsStart,
+ stock.MoveAddLotsStartLot,
+ stock.ShipmentIn,
+ stock.ShipmentOut,
+ stock.ShipmentOutReturn,
+ stock.ShipmentInternal,
+ stock.Period,
+ stock.PeriodCacheLot,
+ stock.Inventory,
+ stock.InventoryLine,
+ stock.InventoryCountSearch,
+ product.Configuration,
+ product.ConfigurationDefaultLotSequence,
+ product.Template,
+ product.Product,
+ module='stock_lot', type_='model')
+ Pool.register(
+ stock.MoveAddLots,
+ stock.InventoryCount,
+ module='stock_lot', type_='wizard')
+ Pool.register(
+ stock.ShipmentDrop,
+ module='stock_lot', type_='model',
+ depends=['sale_supply_drop_shipment'])
diff --git a/modules/stock_lot/doc/index.rst b/modules/stock_lot/doc/index.rst
new file mode 100644
index 0000000000..b4bd2b2c8a
--- /dev/null
+++ b/modules/stock_lot/doc/index.rst
@@ -0,0 +1,11 @@
+Stock Lot Module
+################
+
+The stock lot module defines lot of products.
+
+Lot
+***
+
+A lot is by default just a number to tag moves.
+It is possible to define per product when the lot is required by selecting the
+type of location involved in the move.
diff --git a/modules/stock_lot/ir.xml b/modules/stock_lot/ir.xml
new file mode 100644
index 0000000000..91a87901a7
--- /dev/null
+++ b/modules/stock_lot/ir.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+ Stock Lot
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot/locale/bg.po b/modules/stock_lot/locale/bg.po
new file mode 100644
index 0000000000..2625747b23
--- /dev/null
+++ b/modules/stock_lot/locale/bg.po
@@ -0,0 +1,491 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr "Въведете партида"
+
+#, fuzzy
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Въведете партида"
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr "Въведете партида"
+
+#, fuzzy
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Въведете партида"
+
+#, fuzzy
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Партида"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Планирано количество"
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "Номер"
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "Продукт"
+
+#, fuzzy
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "Количество"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "Записано на"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Партида"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Продукт"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "Количество"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Планирано количество"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Партида"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Продукт"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "Количество"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "Записано на"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Местоположение"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "Записано на"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Партида"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Продукт"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "Количество"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "Количество"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "Номер"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Продукт"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "Количество"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr "Вътрешно количество"
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "Местоположение"
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Партида"
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "Период"
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "Продукт"
+
+#, fuzzy
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "Вида местонахождение за което е необходима партидата"
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+#, fuzzy
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "Вида местонахождение за което е необходима партидата"
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr "Планирано количество"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr "Планирано количество"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Местоположение"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr "Наличност на партида"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr "Наличност на партида"
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr ""
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Местоположение"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Партида"
+
+#, fuzzy
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Партиди"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/ca.po b/modules/stock_lot/locale/ca.po
new file mode 100644
index 0000000000..ff1e4ac60a
--- /dev/null
+++ b/modules/stock_lot/locale/ca.po
@@ -0,0 +1,445 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr "Seqüència de lot per defecte"
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr "Seqüència de lot per defecte"
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr "Lot obligatori"
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Seqüència del lot"
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr "Lot obligatori"
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Seqüència del lot"
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr "UdM per defecte"
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr "Dígits de l'unitat per defecte"
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Quantitat prevista"
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr "Té seqüència"
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "Número"
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "Producte"
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "Quantitat"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr "Document"
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr "Traçabilitat descendent"
+
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Producte"
+
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "Quantitat"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr "Albarà"
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr "Unitat"
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr "Traçabilitat ascendent"
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr "A data"
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr "A data"
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr "UdM per defecte"
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr "Decimals de la UdM per defecte"
+
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Quantitat prevista"
+
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Producte"
+
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "Quantitat"
+
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "A data"
+
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Ubicacions"
+
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "A data"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr "Magatzem"
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr "Duplica número de lot"
+
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Producte"
+
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "Quantitat"
+
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "Quantitat restant"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr "Unitat"
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr "Té seqüència"
+
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "Número"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr "Pare"
+
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Producte"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "Quantitat"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr "Unitat"
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr "Precàlculs de lot"
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr "Quantitat interna"
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "Ubicació"
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "Període"
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "Producte"
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "El tipus d'ubicació per la qual el lot és obligatori."
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr "La seqüència utilitzada per numerar automàticament els lots."
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "El tipus d'ubicació per la qual el lot és obligatori."
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr "La seqüència utilitzada per numerar automàticament els lots."
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Permet calcular les quantitats previstes per a aquesta data.\n"
+"* Un valor buit és un data infinita en el futur.\n"
+"* Una data en el passat proporcionarà valors històrics."
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Permet calcular les quantitats previstes per a aquesta data.\n"
+"* Un valor buit és un data infinita en el futur.\n"
+"* Una data en el passat proporcionarà valors històrics."
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr "El nombre de vegades que s’ha de duplicar el lot."
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr "Quantitat per ubicacions (llistat)"
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr "Quantitat per ubicacions"
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr "Traçabilitat descendent"
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr "Traçabilitat ascendent"
+
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Lots per ubicació"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr "Lots per magatzem"
+
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Afgeix lots"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr "No podeu canviar el producte d'un lot que te moviments d'existències."
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr "Per moure el producte \"%(product)s\" heu d'especificar-n'he el lot."
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+"La quantitat total \"%(lot_quantity)s\" dels lots ha de ser inferior o igual"
+" a la quantitat \"%(move_quantity)s\" del moviment."
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr "Heu de seleccionar un lot en comptes d'un producte per \"%(product)s\"."
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr "Traçabilitat descendent"
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr "Traçabilitat ascendent"
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr "Duplica lot"
+
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Afegir lots"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr "Usuari a les empreses"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr "Lot"
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr "Configuració de les seqüències de lots"
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr "Lot"
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr "Traçabilitat del lot"
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr "Lot per ubicació"
+
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Lots per ubicació"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr "Lots per Magatzem"
+
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Afegir lots"
+
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Afegir lots"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr "Període d'existències precalculat per lot"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Client"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Perdut i trobat"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Producció"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Intern"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Proveïdor"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Client"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Perdut i trobat"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Producció"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Intern"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Proveïdor"
+
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr "Restant:"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr "vegades"
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr "Afegeix"
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr "Cancel·la"
diff --git a/modules/stock_lot/locale/cs.po b/modules/stock_lot/locale/cs.po
new file mode 100644
index 0000000000..aeb2eecb10
--- /dev/null
+++ b/modules/stock_lot/locale/cs.po
@@ -0,0 +1,468 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr ""
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Production"
+
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Lot"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Production"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Lot"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Lot"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Lot"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr ""
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Production"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Lot"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Lot"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/de.po b/modules/stock_lot/locale/de.po
new file mode 100644
index 0000000000..e345f5a2cf
--- /dev/null
+++ b/modules/stock_lot/locale/de.po
@@ -0,0 +1,455 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr "Standard Nummernkreis Charge"
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr "Standard Nummernkreis Charge"
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr "Charge erforderlich für Lagerort"
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Nummernkreis Charge"
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr "Charge erforderlich für Lagerort"
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Nummernkreis Charge"
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Charge"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr "Standardeinheit"
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr "Nachkommastellen Standardmaßeinheit"
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Voraussichtliche Menge"
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr "Hat Nummernkreis"
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "Nummer"
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "Artikel"
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "Menge"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr "Unternehmen"
+
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "Datum"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr "Dokument"
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr "Retrograde Rückverfolgung"
+
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Charge"
+
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Artikel"
+
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "Menge"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr "Lieferung"
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr "Einheit"
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr "Progressive Rückverfolgung"
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr "Ermittlungsdatum"
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr "Ermittlungsdatum"
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr "Standardeinheit"
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr "Standardmaßeinheit Nachkommastellen"
+
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Voraussichtliche Menge"
+
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Charge"
+
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Artikel"
+
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "Menge"
+
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "Ermittlungsdatum"
+
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Lagerorte"
+
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "Ermittlungsdatum"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr "Logistikstandort"
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Charge"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr "Chargennummer Duplizieren"
+
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Chargen"
+
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Artikel"
+
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "Menge"
+
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "Verbleibende Menge"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr "Einheit"
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr "Hat Nummernkreis"
+
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "Nummer"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr "Übergeordnet"
+
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Artikel"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "Menge"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr "Einheit"
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr "Caches Charge"
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr "Interne Menge"
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "Ort"
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Charge"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "Lagerbuchungszeitraum"
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "Artikel"
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "Typ des Lagerorts, für den eine Chargen-Nummer erforderlich ist."
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+"Der Nummernkreis der zur automatischen Nummerierung der Chargen verwendet "
+"wird."
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "Typ des Lagerorts, für den eine Chargen-Nummer erforderlich ist."
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+"Der Nummernkreis der zur automatischen Nummerierung der Chargen verwendet "
+"wird."
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Den erwarteten Lagerbestand für dieses Datum ermitteln.\n"
+"* Ein leerer Wert bedeutet ein unendliches Datum in der Zukunft.\n"
+"* Ein Wert in der Vergangenheit berechnet historische Werte."
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Den erwarteten Lagerbestand für dieses Datum ermitteln.\n"
+"* Ein leerer Wert bedeutet ein unendliches Datum in der Zukunft.\n"
+"* Ein Wert in der Vergangenheit berechnet historische Werte."
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr "Wie oft die Charge dupliziert werden muss."
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr "Lagerbestand je Lagerort"
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr "Lagerbestand (Strukturansicht)"
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Chargen"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr "Retrograde Rückverfolgung"
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr "Progressive Rückverfolgung"
+
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Chargen pro Lagerort"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr "Chargen pro Logistikstandort"
+
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Chargen Hinzufügen"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+"Der Artikel einer Charge, für die es Warenbewegungen gibt, kann nicht "
+"geändert werden."
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+"Damit der Artikel \"%(product)s\" umgelagert werden kann, muss eine Charge "
+"angegeben werden."
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+"Die Gesamtmenge \"%(lot_quantity)s\" der Chargen muss kleiner oder gleich "
+"der Menge \"%(move_quantity)s\" der Warenbewegung sein."
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+"Für \"%(product)s\" muss eine Charge ausgewählt werden anstatt einem "
+"Artikel."
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr "Retrograde Rückverfolgung"
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr "Progressive Rückverfolgung"
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr "Charge Duplizieren"
+
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Chargen Hinzufügen"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr "Benutzer im Unternehmen"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr "Lager Charge"
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Chargen"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr "Artikel Einstellungen Standardnummernkreise Charge"
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr "Lager Charge"
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr "Chargenverfolgung"
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr "Chargen nach Lagerort"
+
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Chargen pro Lagerort"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr "Charge nach Logistikstandort"
+
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Chargen Hinzufügen"
+
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Chargen Hinzufügen"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr "Lagerbuchungszeitraum Cache pro Charge"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Kunde"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Inventurdifferenz"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Produktion"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Lager"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Lieferant"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Kunde"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Inventurdifferenz"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Produktion"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Lager"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Lieferant"
+
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Charge"
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Chargen"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr "Verbleibend:"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr "mal"
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr "Hinzufügen"
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr "Abbrechen"
diff --git a/modules/stock_lot/locale/es.po b/modules/stock_lot/locale/es.po
new file mode 100644
index 0000000000..fc07863cd2
--- /dev/null
+++ b/modules/stock_lot/locale/es.po
@@ -0,0 +1,447 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr "Secuencia de lote por defecto"
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr "Secuencia de lote por defecto"
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr "Lote obligatorio"
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Secuencia de lote"
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr "Lote obligatorio"
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Secuencia de lote"
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Lote"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr "UdM por defecto"
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr "Decimales de unidad por defecto"
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Cantidad prevista"
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr "Tiene secuencia"
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "Número"
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "Producto"
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "Cantidad"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "Fecha"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr "Documento"
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr "Trazabilidad descendente"
+
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Lote"
+
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Producto"
+
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "Cantidad"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr "Albarán"
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr "Unidad"
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr "Trazabilidad ascendente"
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr "A la fecha"
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr "A la fecha"
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr "UdM por defecto"
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr "Decimales de la UdM por defecto"
+
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Cantidad prevista"
+
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Lote"
+
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Producto"
+
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "Cantidad"
+
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "A la fecha"
+
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Ubicaciones"
+
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "A la fecha"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr "Almacén"
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Lote"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr "Duplicar número de lote"
+
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Lotes"
+
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Producto"
+
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "Cantidad"
+
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "Cantidad restante"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr "Unidad"
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr "Tiene secuencia"
+
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "Número"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr "Padre"
+
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Producto"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "Cantidad"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr "Unidad"
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr "Lote precalculado"
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr "Cantidad interna"
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "Ubicación"
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Lote"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "Periodo"
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "Producto"
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "El tipo de ubicación en la que el lote es obligatorio."
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr "La secuencia usada para numerar automáticamente los lotes."
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "El tipo de ubicación en la que el lote es obligatorio."
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr "La secuencia usada para numerar automáticamente los lotes."
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Permite calcular las cantidades previstas para esta fecha.\n"
+"* Un valor vacío es una fecha infinita en el futuro.\n"
+"* Una fecha en el pasado proporcionará valores históricos."
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Permite calcular las cantidades previstas para esta fecha.\n"
+"* Un valor vacío es una fecha infinita en el futuro.\n"
+"* Una fecha en el pasado proporcionará valores históricos."
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr "El número de veces que el lote debe ser duplicado."
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr "Cantidad por ubicaciones (listado)"
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr "Cantidad por ubicaciones"
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Lotes"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr "Trazabilidad descendente"
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr "Trazabilidad ascendente"
+
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Lotes por ubicación"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr "Lotes por almacén"
+
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Añadir lotes"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+"No puede cambiar el producto de un lote que ya tiene movimientos de "
+"existencias."
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr "Para mover el producto \"%(product)s\" debe especificar su lote."
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+"La cantidad total \"%(lot_quantity)s\" de los lotes debe ser menor o igual "
+"que la cantidad \"%(move_quantity)s\" del movimiento."
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr "Debe seleccionar un lote en lugar de un producto en \"%(product)s\"."
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr "Trazabilidad descendente"
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr "Trazabilidad ascendente"
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr "Duplicar lote"
+
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Añadir lotes"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr "Usuario en las empresas"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr "Lote"
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Lotes"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr "Configuración de las secuencias de lotes"
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr "Lote"
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr "Trazabilidad del lote"
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr "Lote por ubicación"
+
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Lotes por ubicación"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr "Lote por almacén"
+
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Añadir lotes"
+
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Añadir lotes"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr "Periodo de existencias precalculado por lote"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Cliente"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Perdido y encontrado"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Producción"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Interno"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Proveedor"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Cliente"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Perdido y encontrado"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Producción"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Interno"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Proveedor"
+
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Lote"
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Lotes"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr "Restante:"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr "veces"
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr "Añadir"
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr "Cancelar"
diff --git a/modules/stock_lot/locale/es_419.po b/modules/stock_lot/locale/es_419.po
new file mode 100644
index 0000000000..edf309c82f
--- /dev/null
+++ b/modules/stock_lot/locale/es_419.po
@@ -0,0 +1,442 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr "Lote requerido"
+
+#, fuzzy
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Lote requerido"
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr "Lote requerido"
+
+#, fuzzy
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Lote requerido"
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr ""
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr ""
+
+#, fuzzy
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "El tipo de ubicación para la cual el lote es requerido"
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+#, fuzzy
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "El tipo de ubicación para la cual el lote es requerido"
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr "Lote de stock"
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr ""
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr "Lote de stock"
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr ""
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr ""
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr ""
+
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/et.po b/modules/stock_lot/locale/et.po
new file mode 100644
index 0000000000..2ec65d049b
--- /dev/null
+++ b/modules/stock_lot/locale/et.po
@@ -0,0 +1,476 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr "Partii nõutav"
+
+#, fuzzy
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Partii nõutav"
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr "Partii nõutav"
+
+#, fuzzy
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Partii nõutav"
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Partii"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Prognoositav kogus"
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "Number"
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "Toode"
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "Kogus"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "Kuupäeval"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Partii"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Toode"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "Kogus"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr "Kuupäeval"
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr "Kuupäeval"
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Prognoositav kogus"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Partii"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Toode"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "Kogus"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "Kuupäeval"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Asukoht"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "Kuupäeval"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Partii"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Partiid"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Toode"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "Kogus"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "Kogus"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "Number"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Toode"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "Kogus"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr "Sisemine kogus"
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "Asukoht"
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Partii"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "Periood"
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "Toode"
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr "Prognoositav kogus"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr "Prognoositav kogus"
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Partiid"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Asukoht"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Partiid"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Partiid"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr "Partii laos"
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Partiid"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr "Partii laos"
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr ""
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Asukoht"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Partiid"
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Partiid"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Klient"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Kaotatud ja leitud"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Tootmine"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Laokoht"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Hankija"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Klient"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Kaotatud ja leitud"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Tootmine"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Laokoht"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Hankija"
+
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Partii"
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Partiid"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/fa.po b/modules/stock_lot/locale/fa.po
new file mode 100644
index 0000000000..ae9fdeb98e
--- /dev/null
+++ b/modules/stock_lot/locale/fa.po
@@ -0,0 +1,490 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr "قطعه مورد نیاز"
+
+#, fuzzy
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "قطعه مورد نیاز"
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr "قطعه مورد نیاز"
+
+#, fuzzy
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "قطعه مورد نیاز"
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "قطعه"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "مقدار پیش بینی شده"
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "شماره"
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "محصول"
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "مقدار/تعداد"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "در تاریخ"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "قطعه"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "محصول"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "مقدار/تعداد"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr "در تاریخ"
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr "در تاریخ"
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "مقدار پیش بینی شده"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "قطعه"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "محصول"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "مقدار/تعداد"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "در تاریخ"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "مکان"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "در تاریخ"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "قطعه"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "قطعهها"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "محصول"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "مقدار/تعداد"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "مقدار/تعداد"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "شماره"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "محصول"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "مقدار/تعداد"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr "مخازن قطعه"
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr "مقدار داخلی"
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "مکان"
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "قطعه"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "دوره زمانی"
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "محصول"
+
+#, fuzzy
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "نوع مکانی که نیازمند قطعه میباشد"
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+#, fuzzy
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "نوع مکانی که نیازمند قطعه میباشد"
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"اجازه می دهد مقادیرموجودی مورد انتظار را برای این تاریخ محاسبه کنید.\n"
+"* مقدار خالی یک تاریخ درآینده نامحدود است.\n"
+"* یک تاریخ در گذشته ارزش های تاریخی را فراهم می کند."
+
+#, fuzzy
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"اجازه می دهد مقادیرموجودی مورد انتظار را برای این تاریخ محاسبه کنید.\n"
+"* مقدار خالی یک تاریخ درآینده نامحدود است.\n"
+"* یک تاریخ در گذشته ارزش های تاریخی را فراهم می کند."
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr "مقدار پیش بینی شده"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr "مقدار پیش بینی شده"
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "قطعهها"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "قطعه بواسطه مکان"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "قطعهها"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+"شما نمیتوانید محصول زیادی از یک جنس را تغییر دهید که جابجایی اجناس داشته "
+"باشد."
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+"برای جابجایی محصول :\"%(product)s\" شما باید یک قطعه از جنس را ارائه کنید."
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+"شما باید یک مقدار جنس را به جای یک محصول برای \"%(product)s\" انتخاب کنید."
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "قطعهها"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr "قطعه موجود"
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "قطعهها"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr "قطعه موجود"
+
+#, fuzzy
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr "مخازن قطعه"
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr "قطعه بواسطه مکان"
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "قطعه بواسطه مکان"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "قطعهها"
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "قطعهها"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr "موجودی دوره انبار در هر قطعه"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "مشتری"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "گمشده ها و یافته ها"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "تهیه کننده"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "مخزن"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "تأمین کننده"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "مشتری"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "گمشده ها و یافته ها"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "تهیه کننده"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "مخزن"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "تأمین کننده"
+
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "قطعه"
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "قطعهها"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/fi.po b/modules/stock_lot/locale/fi.po
new file mode 100644
index 0000000000..6e23f07970
--- /dev/null
+++ b/modules/stock_lot/locale/fi.po
@@ -0,0 +1,466 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr ""
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Production"
+
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Production"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr ""
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Production"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/fr.po b/modules/stock_lot/locale/fr.po
new file mode 100644
index 0000000000..d9136a41df
--- /dev/null
+++ b/modules/stock_lot/locale/fr.po
@@ -0,0 +1,448 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr "Séquence de lot par défaut"
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr "Séquence de lot par défaut"
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr "Lot requis"
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Séquence de lot"
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr "Lot requis"
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Séquence de lot"
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr "UDM par défaut"
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr "Décimales d'unité par défaut"
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Quantité prévisionnelle"
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr "A une séquence"
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "Numéro"
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "Produit"
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "Quantité"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr "Société"
+
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "Date"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr "Document"
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr "Traces descendantes"
+
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Produit"
+
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "Quantité"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr "Expédition"
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr "Unité"
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr "Traces ascendantes"
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr "À la date"
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr "À la date"
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr "UDM par défaut"
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr "Décimales d'UDM par défaut"
+
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Quantité prévisionnelle"
+
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Produit"
+
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "Quantité"
+
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "À la date"
+
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Emplacements"
+
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "À la date"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr "Entrepôt"
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr "Dupliquer le numéro de lot"
+
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Produit"
+
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "Quantité"
+
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "Quantité restante"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr "Unité"
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr "A une séquence"
+
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "Numéro"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr "Parent"
+
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Produit"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "Quantité"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr "Unité"
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr "Caches de lot"
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr "Quantité interne"
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "Emplacement"
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "Période"
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "Produit"
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "Le type d'emplacement pour lequel un lot est requis."
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr "La séquence utilisée pour numéroter automatiquement les lots."
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "Le type d'emplacement pour lequel un lot est requis."
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr "La séquence utilisée pour numéroter automatiquement les lots."
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Permet de calculer les quantités de stock attendues pour cette date.\n"
+"* Une valeur vide est une date infinie dans le futur.\n"
+"* Une date dans le passé fournira les valeurs historiques."
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Permet de calculer les quantités de stock attendues pour cette date.\n"
+"* Une valeur vide est une date infinie dans le futur.\n"
+"* Une date dans le passé fournira les valeurs historiques."
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr "Le nombre de fois que le lot doit être dupliqué."
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr "Liste des quantités par emplacements"
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr "Arbre des quantité par emplacements"
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr "Traces descendantes"
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr "Traces ascendantes"
+
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Lots par emplacements"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr "Lots par entrepôt"
+
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Ajouter des lots"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+"Vous ne pouvez pas changer le produit d'un lot qui a des mouvements de "
+"stock."
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr "Pour déplacer le produit « %(product)s », vous devez fournir un lot."
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+"La quantité totale « %(lot_quantity)s » des lots doit être inférieure ou "
+"égale à la quantité « %(move_quantity)s » du mouvement."
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+"Vous devez sélectionner un lot au lieu d'un produit pour « %(product)s »."
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr "Traces descendantes"
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr "Traces ascendantes"
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr "Dupliquer le lot"
+
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Ajouter des lots"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr "Utilisateur dans les sociétés"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr "Lot"
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr "Configuration produit Séquence de lot par défaut"
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr "Lot"
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr "Suivi des lots"
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr "Lot par emplacement"
+
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Lots par emplacements"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr "Lot par entrepôt"
+
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Ajouter des lots"
+
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Ajouter des lots"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr "Caches de période de stock par lot"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Client"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Pertes et surplus"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Magasin"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Fournisseur"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Client"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Pertes et surplus"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Magasin"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Fournisseur"
+
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr "Restant :"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr "fois"
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr "Ajouter"
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr "Annuler"
diff --git a/modules/stock_lot/locale/hu.po b/modules/stock_lot/locale/hu.po
new file mode 100644
index 0000000000..946e5fa0ac
--- /dev/null
+++ b/modules/stock_lot/locale/hu.po
@@ -0,0 +1,483 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr "Charge szükséges a raktárhelyhez "
+
+#, fuzzy
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Charge szükséges a raktárhelyhez "
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr "Charge szükséges a raktárhelyhez"
+
+#, fuzzy
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Charge szükséges a raktárhelyhez "
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Charge"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Előrelátható mennyiség"
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "Szám"
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "Termék"
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "Mennyiség"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "Utolsó módosítás dátuma"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Charge"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Termék"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "Mennyiség"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Előrelátható mennyiség"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Charge"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Termék"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "Mennyiség"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "Utolsó módosítás dátuma"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Hely"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "Utolsó módosítás dátuma"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Charge"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Termék"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "Mennyiség"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "Mennyiség"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "Szám"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Termék"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "Mennyiség"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr "Caches Charge"
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr "Belső mennyiség"
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "Hely"
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Charge"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "Raktár időszak"
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "Termék"
+
+#, fuzzy
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "Raktárhely típusa, melyhez szükséges Charge szám"
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+#, fuzzy
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "Raktárhely típusa, melyhez szükséges Charge szám"
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr "Előrelátható mennyiség"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr "Előrelátható mennyiség"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Hely"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr "Raktár Charge"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr "Raktár Charge"
+
+#, fuzzy
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr "Caches Charge"
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Hely"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr "Raktár Cache időszak Chargenként"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Charge"
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Chargen"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/id.po b/modules/stock_lot/locale/id.po
new file mode 100644
index 0000000000..59a821294b
--- /dev/null
+++ b/modules/stock_lot/locale/id.po
@@ -0,0 +1,443 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "Nomor"
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "Produk"
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr "Perusahaan"
+
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "Tanggal"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr "Dokumen"
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Produk"
+
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "Kuantitas"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr "Pada Tanggal"
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr "Pada Tanggal"
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Produk"
+
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "Pada Tanggal"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Lokasi"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "Pada Tanggal"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr "Gudang"
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Produk"
+
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "Kuantitas"
+
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "Nomor"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr "Induk"
+
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Produk"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "Lokasi"
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "Periode"
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "Produk"
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Lokasi"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr ""
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr ""
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Lokasi"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Pelanggan"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Produksi"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Pemasok"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Pelanggan"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Produksi"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Pemasok"
+
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/it.po b/modules/stock_lot/locale/it.po
new file mode 100644
index 0000000000..aa632c3c17
--- /dev/null
+++ b/modules/stock_lot/locale/it.po
@@ -0,0 +1,463 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Lotto"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr "UdM predefinita"
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Quantità prevista"
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "Numero"
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "Prodotto"
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "Quantità"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "Utente scrittura"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Lotto"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Prodotto"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "Quantità"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Quantità prevista"
+
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Lotto"
+
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Prodotto"
+
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "Quantità"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "Utente scrittura"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Luogo"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "Utente scrittura"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr "Magazzino"
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Lotto"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Lotti"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Prodotto"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "Quantità"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "Quantità"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "Numero"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Prodotto"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "Quantità"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "Luogo"
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Lotto"
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "Periodo"
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "Prodotto"
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr "Quantità prevista"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr "Quantità prevista"
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Lotti"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Luogo"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Lot"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Lot"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Lotti"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr ""
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Luogo"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Lot"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Cliente"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Perso e ritrovato"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Deposito"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Fornitore"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Cliente"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Perso e ritrovato"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Deposito"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Fornitore"
+
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Lotto"
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Lotti"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/lo.po b/modules/stock_lot/locale/lo.po
new file mode 100644
index 0000000000..24ccbce21c
--- /dev/null
+++ b/modules/stock_lot/locale/lo.po
@@ -0,0 +1,482 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "ເລກທີ"
+
+#, fuzzy
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "ຜະລິດຕະພັນ"
+
+#, fuzzy
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "ຈຳນວນ"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "ວັນທີບັນທຶກ"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "ຜະລິດຕະພັນ"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "ຈຳນວນ"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "ຈຳນວນພາຍໃນ"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "ຜະລິດຕະພັນ"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "ຈຳນວນ"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "ວັນທີບັນທຶກ"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "ບ່ອນຢູ່"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "ວັນທີບັນທຶກ"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "ຜະລິດຕະພັນ"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "ຈຳນວນ"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "ຈຳນວນ"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "ເລກທີ"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "ຜະລິດຕະພັນ"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "ຈຳນວນ"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr "ຈຳນວນພາຍໃນ"
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "ບ່ອນຢູ່"
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "ໄລຍະ"
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "ຜະລິດຕະພັນ"
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "ບ່ອນຢູ່"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr ""
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "ບ່ອນຢູ່"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "ລໍຮັບຈ່າຍ"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "ຜະລິດຕະພັນ"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "ຫ້ອງເກັບມ້ຽນຢາ"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "ຜູ້ສະໜອງ"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "ລໍຮັບຈ່າຍ"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "ຜະລິດຕະພັນ"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "ຫ້ອງເກັບມ້ຽນຢາ"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "ຜູ້ສະໜອງ"
+
+#, fuzzy
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/lt.po b/modules/stock_lot/locale/lt.po
new file mode 100644
index 0000000000..cef192d912
--- /dev/null
+++ b/modules/stock_lot/locale/lt.po
@@ -0,0 +1,471 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Lo"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr ""
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "Pakeitimo data"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Lo"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Lo"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "Pakeitimo data"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "Pakeitimo data"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Lo"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Lo"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Lo"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Lo"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Production"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Lo"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Lo"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Lo"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr ""
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Production"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Lo"
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Lo"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Lo"
+
+#, fuzzy
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Lo"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/nl.po b/modules/stock_lot/locale/nl.po
new file mode 100644
index 0000000000..7466ae79f1
--- /dev/null
+++ b/modules/stock_lot/locale/nl.po
@@ -0,0 +1,448 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr "Standaard batchvolgorde"
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr "Standaard batchvolgorde"
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr "Batch vereist"
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Batch volgorde"
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr "Batch vereist"
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Batch volgorde"
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Batch"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr "Standaard maateenheid"
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr "Standaard maateenheid decimalen"
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Verwachte hoeveelheid"
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr "Heeft reeks"
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "Nummer"
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "Product"
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "Hoeveelheid"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr "Bedrijf"
+
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "Datum"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr "Document"
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr "Neerwaartse tracering"
+
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Batch"
+
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Product"
+
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "Hoeveelheid"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr "Zending"
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr "Eenheid"
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr "Opwaartse tracering"
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr "Op datum"
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr "Op datum"
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr "Standaard maateenheid"
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr "Standaard maateenheid decimalen"
+
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Verwachte hoeveelheid"
+
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Batch"
+
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Product"
+
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "Hoeveelheid"
+
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "Op datum"
+
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Locaties"
+
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "Op datum"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr "Magazijn"
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Batch"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr "Dupliceer batchnummer"
+
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Batches"
+
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Product"
+
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "Hoeveelheid"
+
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "Resterende hoeveelheid"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr "Eenheid"
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr "Heeft reeks"
+
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "Nummer"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr "Bovenliggend"
+
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Product"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "Hoeveelheid"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr "Eenheid"
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr "Batch Caches"
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr "Interne hoeveelheid"
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "Plaats"
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Batch"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "Periode"
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "Product"
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "Het soort locatie waarvoor een batch vereist is."
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr "De volgorde die wordt gebruikt om batches automatisch te nummeren."
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "Het soort locatie waarvoor een batch vereist is."
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr "De volgorde die wordt gebruikt om batches automatisch te nummeren."
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Sta toe de verwachte voorraadhoeveelheden voor deze datum te berekenen.\n"
+"* Een lege waarde is een oneindige datum in de toekomst.\n"
+"* Een datum in het verleden levert historische waarden op."
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Sta toe de verwachte voorraadhoeveelheden voor deze datum te berekenen.\n"
+"* Een lege waarde is een oneindige datum in de toekomst.\n"
+"* Een datum in het verleden levert historische waarden op."
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr "Het aantal keren dat de batch gedupliceerd moet worden."
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr "Lijst met hoeveelheden per locatie"
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr "Boomstructuur met hoeveelheden per locatie"
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Batches"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr "Neerwaartse tracering"
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr "Opwaartse tracering"
+
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Batches per locatie"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr "Batches per magazijn"
+
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Batches toevoegen"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+"U kunt het product van een batch die voorraadbewegingen heeft niet wijzigen."
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr "Om product \"%(product)s\" te verplaatsen, moet u een batch opgeven."
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+"De totale hoeveelheid \"%(lot_quantity)s\" van de batches moet kleiner of "
+"gelijk zijn aan de hoeveelheid \"%(move_quantity)s\" van de "
+"voorraadbeweging."
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+"U moet een batch selecteren in plaats van een product voor \"%(product)s\"."
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr "Neerwaartse tracering"
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr "Opwaartse tracering"
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr "Dupliceer batch"
+
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Batches toevoegen"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr "Gebruiker in bedrijven"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr "Voorraad batch"
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Batches"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr "Productconfiguratie Standaard Batchvolgorde"
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr "Voorraad batch"
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr "Batch tracering"
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr "Batch per locatie"
+
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Batches per locatie"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr "Batch per magazijn"
+
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Batches toevoegen"
+
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Batches toevoegen"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr "Voorraadperiode Cache per batch"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Klant"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Voorraad verschil"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Productie"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Magazijn"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Leverancier"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Klant"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Voorraad verschil"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Productie"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Magazijn"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Leverancier"
+
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Batch"
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Batches"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr "Overig:"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr "keer"
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr "Toevoegen"
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr "Annuleer"
diff --git a/modules/stock_lot/locale/pl.po b/modules/stock_lot/locale/pl.po
new file mode 100644
index 0000000000..f6f810c31b
--- /dev/null
+++ b/modules/stock_lot/locale/pl.po
@@ -0,0 +1,478 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "Numer"
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "Produkt"
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "Ilość"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "Na dzień"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Produkt"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "Ilość"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr "Na dzień"
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr "Na dzień"
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Ilość"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Produkt"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "Ilość"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "Na dzień"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Lokalizacja"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "Na dzień"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Produkt"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "Ilość"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "Ilość"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "Numer"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Produkt"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "Ilość"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "Lokalizacja"
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "Okres"
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "Produkt"
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Lokalizacja"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr ""
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Lokalizacja"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/pt.po b/modules/stock_lot/locale/pt.po
new file mode 100644
index 0000000000..2372daa772
--- /dev/null
+++ b/modules/stock_lot/locale/pt.po
@@ -0,0 +1,489 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr "Lote Obrigatório"
+
+#, fuzzy
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Lote Obrigatório"
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr "Lote Obrigatório"
+
+#, fuzzy
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Lote Obrigatório"
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Lote"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Quantidade prevista"
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "Número"
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "Produto"
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "Quantidade"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "Na Data"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Lote"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Produto"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "Quantidade"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr "Na Data"
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr "Na Data"
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Quantidade prevista"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Lote"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Produto"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "Quantidade"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "Na Data"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Localização"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "Na Data"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Lote"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Produto"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "Quantidade"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "Quantidade"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "Número"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Produto"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "Quantidade"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr "Lotes pré-calculados"
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr "Quantidade interna"
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "Localização"
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Lote"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "Período"
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "Produto"
+
+#, fuzzy
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "O tipo de localização para a qual o lote é obrigatório"
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+#, fuzzy
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "O tipo de localização para a qual o lote é obrigatório"
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Permite o cálculo esperado das quantidades do estoque para esta data.\n"
+"* Um valor vazio é uma data infinita no futuro.\n"
+"* Uma data no passado mostrará valores históricos."
+
+#, fuzzy
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Permite o cálculo esperado das quantidades do estoque para esta data.\n"
+"* Um valor vazio é uma data infinita no futuro.\n"
+"* Uma data no passado mostrará valores históricos."
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr "Quantidade prevista"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr "Quantidade prevista"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Lote Localização"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr "Lote de estoque"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr "Lote de estoque"
+
+#, fuzzy
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr "Lotes pré-calculados"
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr "Lote Localização"
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Lote Localização"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr "Período de estoque pré-calculado por lote"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Lote"
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Lotes"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/ro.po b/modules/stock_lot/locale/ro.po
new file mode 100644
index 0000000000..c8ec3fb0e7
--- /dev/null
+++ b/modules/stock_lot/locale/ro.po
@@ -0,0 +1,441 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr ""
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "Produs"
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Produs"
+
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Produs"
+
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Produs"
+
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Produs"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "Perioadă"
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "Produs"
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr "Locaţii Lista Cantităţi"
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr "Arbore Cantitate Locaţii"
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr ""
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr ""
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr ""
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr ""
+
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/ru.po b/modules/stock_lot/locale/ru.po
new file mode 100644
index 0000000000..71c1381064
--- /dev/null
+++ b/modules/stock_lot/locale/ru.po
@@ -0,0 +1,486 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Прогноз количества"
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "Номер"
+
+#, fuzzy
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "Товарно материальные ценности (ТМЦ)"
+
+#, fuzzy
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "Кол-во"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "Дата изменения"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Товарно материальные ценности (ТМЦ)"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "Кол-во"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Прогноз количества"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Товарно материальные ценности (ТМЦ)"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "Кол-во"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "Дата изменения"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Местоположение"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "Дата изменения"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Товарно материальные ценности (ТМЦ)"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "Кол-во"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "Кол-во"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "Номер"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Товарно материальные ценности (ТМЦ)"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "Кол-во"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr "Внутреннее количество"
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "Местоположение"
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "Период"
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "Товарно материальные ценности (ТМЦ)"
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr "Прогноз количества"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr "Прогноз количества"
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Местоположение"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr ""
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Местоположение"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Заказчик"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Утраченный и обретенный"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Производство"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Хранилище"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Поставщик"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Заказчик"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Утраченный и обретенный"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Производство"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Хранилище"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Поставщик"
+
+#, fuzzy
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/sl.po b/modules/stock_lot/locale/sl.po
new file mode 100644
index 0000000000..d7379d7064
--- /dev/null
+++ b/modules/stock_lot/locale/sl.po
@@ -0,0 +1,489 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr "Serija obvezna"
+
+#, fuzzy
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Serija obvezna"
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr "Serija obvezna"
+
+#, fuzzy
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "Serija obvezna"
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Serija"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Predvidena količina"
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "Številka"
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "Izdelek"
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "Količina"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "Na dan"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Serija"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Izdelek"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "Količina"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr "Na dan"
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr "Na dan"
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Predvidena količina"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Serija"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Izdelek"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "Količina"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "Na dan"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Lokacija"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "Na dan"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Serija"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Izdelek"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "Količina"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "Količina"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "Številka"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Izdelek"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "Količina"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr "Predpomnjene serije"
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr "Notranja količina"
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "Lokacija"
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Serija"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "Obdobje"
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "Izdelek"
+
+#, fuzzy
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "Tip lokacije, za katero je serija obvezna"
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+#, fuzzy
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr "Tip lokacije, za katero je serija obvezna"
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Omogoča izračun predvidenih zalog na ta dan.\n"
+"* Prazno polje pomeni neskončno v prihodnost.\n"
+"* Pretekli datum daje zgodovino zaloge."
+
+#, fuzzy
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Omogoča izračun predvidenih zalog na ta dan.\n"
+"* Prazno polje pomeni neskončno v prihodnost.\n"
+"* Pretekli datum daje zgodovino zaloge."
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr "Predvidena količina"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr "Predvidena količina"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Serija po lokaciji"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr "Serija"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr "Serija"
+
+#, fuzzy
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr "Predpomnjene serije"
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr "Serija po lokaciji"
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Serija po lokaciji"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr "Predpomnjena obdobja po serijah"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Serija"
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Serije"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/tr.po b/modules/stock_lot/locale/tr.po
new file mode 100644
index 0000000000..6e23f07970
--- /dev/null
+++ b/modules/stock_lot/locale/tr.po
@@ -0,0 +1,466 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr ""
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "Production"
+
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "Production"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "Lot"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr "Production"
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr ""
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Production"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "Lots"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "Customer"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "Lost and Found"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "Production"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "Storage"
+
+#, fuzzy
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "Supplier"
+
+#, fuzzy
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "Lot"
+
+#, fuzzy
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "Lots"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/uk.po b/modules/stock_lot/locale/uk.po
new file mode 100644
index 0000000000..34055af361
--- /dev/null
+++ b/modules/stock_lot/locale/uk.po
@@ -0,0 +1,437 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr ""
+
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr ""
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr ""
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr ""
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr ""
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr ""
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr ""
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr ""
+
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr ""
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr ""
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr ""
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr ""
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr ""
+
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/locale/zh_CN.po b/modules/stock_lot/locale/zh_CN.po
new file mode 100644
index 0000000000..992a367691
--- /dev/null
+++ b/modules/stock_lot/locale/zh_CN.po
@@ -0,0 +1,457 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.configuration,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt ""
+"field:product.configuration.default_lot_sequence,default_lot_sequence:"
+msgid "Default Lot Sequence"
+msgstr ""
+
+msgctxt "field:product.product,lot_required:"
+msgid "Lot Required"
+msgstr "需要批次"
+
+#, fuzzy
+msgctxt "field:product.product,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "需要批次"
+
+msgctxt "field:product.template,lot_required:"
+msgid "Lot Required"
+msgstr "需要批次"
+
+#, fuzzy
+msgctxt "field:product.template,lot_sequence:"
+msgid "Lot Sequence"
+msgstr "需要批次"
+
+msgctxt "field:stock.inventory.line,lot:"
+msgid "Lot"
+msgstr "批次"
+
+msgctxt "field:stock.lot,default_uom:"
+msgid "Default UOM"
+msgstr "默认计量单位"
+
+msgctxt "field:stock.lot,default_uom_digits:"
+msgid "Default Unit Digits"
+msgstr "默认单位有效数字"
+
+msgctxt "field:stock.lot,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "预期数量"
+
+msgctxt "field:stock.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+msgctxt "field:stock.lot,number:"
+msgid "Number"
+msgstr "批次号"
+
+msgctxt "field:stock.lot,product:"
+msgid "Product"
+msgstr "产品"
+
+msgctxt "field:stock.lot,quantity:"
+msgid "Quantity"
+msgstr "数量"
+
+msgctxt "field:stock.lot.trace,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,date:"
+msgid "Date"
+msgstr "日期"
+
+msgctxt "field:stock.lot.trace,document:"
+msgid "Document"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,downward_traces:"
+msgid "Downward Traces"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,lot:"
+msgid "Lot"
+msgstr "批次"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,product:"
+msgid "Product"
+msgstr "产品"
+
+#, fuzzy
+msgctxt "field:stock.lot.trace,quantity:"
+msgid "Quantity"
+msgstr "数量"
+
+msgctxt "field:stock.lot.trace,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot.trace,upward_traces:"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "field:stock.lots_by_location.context,forecast_date:"
+msgid "At Date"
+msgstr "日期"
+
+msgctxt "field:stock.lots_by_location.context,stock_date_end:"
+msgid "At Date"
+msgstr "日期"
+
+msgctxt "field:stock.lots_by_locations,default_uom:"
+msgid "Default UOM"
+msgstr "默认计量单位"
+
+msgctxt "field:stock.lots_by_locations,default_uom_digits:"
+msgid "Default UOM Digits"
+msgstr "默认计量单位有效数字"
+
+msgctxt "field:stock.lots_by_locations,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "预期数量"
+
+msgctxt "field:stock.lots_by_locations,lot:"
+msgid "Lot"
+msgstr "批次"
+
+msgctxt "field:stock.lots_by_locations,product:"
+msgid "Product"
+msgstr "产品"
+
+msgctxt "field:stock.lots_by_locations,quantity:"
+msgid "Quantity"
+msgstr "数量"
+
+msgctxt "field:stock.lots_by_warehouse.context,forecast_date:"
+msgid "At Date"
+msgstr "日期"
+
+msgctxt "field:stock.lots_by_warehouse.context,locations:"
+msgid "Locations"
+msgstr "库位"
+
+msgctxt "field:stock.lots_by_warehouse.context,stock_date_end:"
+msgid "At Date"
+msgstr "日期"
+
+msgctxt "field:stock.lots_by_warehouse.context,warehouse:"
+msgid "Warehouse"
+msgstr "仓库"
+
+msgctxt "field:stock.move,lot:"
+msgid "Lot"
+msgstr "批次"
+
+msgctxt "field:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "Duplicate Lot Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,lots:"
+msgid "Lots"
+msgstr "批次"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,product:"
+msgid "Product"
+msgstr "产品"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity:"
+msgid "Quantity"
+msgstr "数量"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start,quantity_remaining:"
+msgid "Quantity Remaining"
+msgstr "数量"
+
+msgctxt "field:stock.move.add.lots.start,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,has_sequence:"
+msgid "Has Sequence"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,number:"
+msgid "Number"
+msgstr "批次号"
+
+msgctxt "field:stock.move.add.lots.start.lot,parent:"
+msgid "Parent"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product:"
+msgid "Product"
+msgstr "产品"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,quantity:"
+msgid "Quantity"
+msgstr "数量"
+
+msgctxt "field:stock.move.add.lots.start.lot,quantity_unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.period,lot_caches:"
+msgid "Lot Caches"
+msgstr "批次缓存"
+
+msgctxt "field:stock.period.cache.lot,internal_quantity:"
+msgid "Internal Quantity"
+msgstr "内部数量"
+
+msgctxt "field:stock.period.cache.lot,location:"
+msgid "Location"
+msgstr "库位"
+
+msgctxt "field:stock.period.cache.lot,lot:"
+msgid "Lot"
+msgstr "批次"
+
+msgctxt "field:stock.period.cache.lot,period:"
+msgid "Period"
+msgstr "周期"
+
+msgctxt "field:stock.period.cache.lot,product:"
+msgid "Product"
+msgstr "产品"
+
+msgctxt "help:product.product,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.product,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:product.template,lot_required:"
+msgid "The type of location for which lot is required."
+msgstr ""
+
+msgctxt "help:product.template,lot_sequence:"
+msgid "The sequence used to automatically number lots."
+msgstr ""
+
+msgctxt "help:stock.lots_by_location.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.lots_by_warehouse.context,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start,duplicate_lot_number:"
+msgid "The number of times the lot must be duplicated."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_location_quantity_list"
+msgid "Locations List Quantity"
+msgstr "库位明细数量"
+
+msgctxt "model:ir.action,name:act_location_quantity_tree"
+msgid "Locations Tree Quantity"
+msgstr "库位树数量"
+
+msgctxt "model:ir.action,name:act_lot_form"
+msgid "Lots"
+msgstr "批次"
+
+msgctxt "model:ir.action,name:act_lot_trace_downward_relate"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lot_trace_upward_relate"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lots_by_locations_relate"
+msgid "Lots by Locations"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_lots_by_warehouse_relate"
+msgid "Lots By Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_move_add_lots"
+msgid "Add Lots"
+msgstr "批次"
+
+msgctxt "model:ir.message,text:msg_change_product"
+msgid "You cannot change the product of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_required"
+msgid "To move product \"%(product)s\" you must provide a stock lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_add_lot_quantity"
+msgid ""
+"The total quantity \"%(lot_quantity)s\" of the lots must be less than or "
+"equal to the quantity \"%(move_quantity)s\" of the move."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_only_lot"
+msgid "You must select a stock lot instead of a product for \"%(product)s\"."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_downward_traces_button"
+msgid "Downward Traces"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:lot_upward_traces_button"
+msgid "Upward Traces"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:move_add_lots_start_duplicate_lot_button"
+msgid "Duplicate Lot"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:move_add_lots_wizard_button"
+msgid "Add Lots"
+msgstr "批次"
+
+msgctxt "model:ir.rule.group,name:rule_group_lot_trace_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.sequence.type,name:sequence_type_stock_lot"
+msgid "Stock Lot"
+msgstr "库存批次"
+
+msgctxt "model:ir.ui.menu,name:menu_lot_form"
+msgid "Lots"
+msgstr "批次"
+
+msgctxt "model:product.configuration.default_lot_sequence,name:"
+msgid "Product Configuration Default Lot Sequence"
+msgstr ""
+
+msgctxt "model:stock.lot,name:"
+msgid "Stock Lot"
+msgstr "库存批次"
+
+#, fuzzy
+msgctxt "model:stock.lot.trace,name:"
+msgid "Lot Trace"
+msgstr "批次缓存"
+
+msgctxt "model:stock.lots_by_location.context,name:"
+msgid "Lot by Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.lots_by_locations,name:"
+msgid "Lots by Locations"
+msgstr "Production"
+
+msgctxt "model:stock.lots_by_warehouse.context,name:"
+msgid "Lot by Warehouse"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start,name:"
+msgid "Add Lots"
+msgstr "批次"
+
+#, fuzzy
+msgctxt "model:stock.move.add.lots.start.lot,name:"
+msgid "Add Lots"
+msgstr "批次"
+
+msgctxt "model:stock.period.cache.lot,name:"
+msgid "Stock Period Cache per Lot"
+msgstr ""
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Customer"
+msgstr "客户"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Lost and Found"
+msgstr "失物招领区"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Production"
+msgstr "产品"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Storage"
+msgstr "存储区"
+
+msgctxt "selection:product.product,lot_required:"
+msgid "Supplier"
+msgstr "供应商"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Customer"
+msgstr "客户"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Lost and Found"
+msgstr "失物招领区"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Production"
+msgstr "产品"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Storage"
+msgstr "存储区"
+
+msgctxt "selection:product.template,lot_required:"
+msgid "Supplier"
+msgstr "供应商"
+
+msgctxt "selection:stock.inventory.count.search,search:"
+msgid "Lot"
+msgstr "批次"
+
+msgctxt "view:product.template:"
+msgid "Lots"
+msgstr "批次"
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "Remaining:"
+msgstr ""
+
+msgctxt "view:stock.move.add.lots.start:"
+msgid "times"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,add:"
+msgid "Add"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.add.lots,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_lot/message.xml b/modules/stock_lot/message.xml
new file mode 100644
index 0000000000..08b54d5eb7
--- /dev/null
+++ b/modules/stock_lot/message.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+ You cannot change the product of a stock lot which has stock moves.
+
+
+ To move product "%(product)s" you must provide a stock lot.
+
+
+ You must select a stock lot instead of a product for "%(product)s".
+
+
+ The total quantity "%(lot_quantity)s" of the lots must be less than or equal to the quantity "%(move_quantity)s" of the move.
+
+
+
diff --git a/modules/stock_lot/product.py b/modules/stock_lot/product.py
new file mode 100644
index 0000000000..4ececa619b
--- /dev/null
+++ b/modules/stock_lot/product.py
@@ -0,0 +1,114 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from sql import Table
+
+from trytond.config import config
+from trytond.model import ModelSQL, ValueMixin, fields
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Eval, Id
+from trytond.transaction import Transaction
+
+
+class Configuration(metaclass=PoolMeta):
+ __name__ = 'product.configuration'
+
+ default_lot_sequence = fields.MultiValue(
+ fields.Many2One(
+ 'ir.sequence', "Default Lot Sequence",
+ domain=[
+ ('sequence_type', '=',
+ Id('stock_lot', 'sequence_type_stock_lot')),
+ ]))
+
+
+class ConfigurationDefaultLotSequence(ModelSQL, ValueMixin):
+ "Product Configuration Default Lot Sequence"
+ __name__ = 'product.configuration.default_lot_sequence'
+ default_lot_sequence = fields.Many2One(
+ 'ir.sequence', "Default Lot Sequence",
+ domain=[
+ ('sequence_type', '=',
+ Id('stock_lot', 'sequence_type_stock_lot')),
+ ])
+
+
+class Template(metaclass=PoolMeta):
+ __name__ = 'product.template'
+
+ lot_required = fields.MultiSelection([
+ ('supplier', "Supplier"),
+ ('customer', "Customer"),
+ ('lost_found', "Lost and Found"),
+ ('storage', "Storage"),
+ ('production', "Production"),
+ ], "Lot Required",
+ help='The type of location for which lot is required.',
+ states={
+ 'invisible': ~Eval('type').in_(['goods', 'assets']),
+ })
+ lot_sequence = fields.Many2One(
+ 'ir.sequence', "Lot Sequence",
+ domain=[
+ ('sequence_type', '=', Id('stock_lot', 'sequence_type_stock_lot')),
+ ],
+ states={
+ 'invisible': ~Eval('type').in_(['goods', 'assets']),
+ },
+ help="The sequence used to automatically number lots.")
+
+ @classmethod
+ def __register__(cls, module):
+ connection = Transaction().connection
+ cursor = connection.cursor()
+
+ super().__register__(module)
+
+ table_h = cls.__table_handler__(module)
+ template_lot_type_table_name = config.get(
+ 'table', 'product.template-stock.lot.type',
+ default='product.template-stock.lot.type' .replace('.', '_'))
+ lot_type_table_name = config.get(
+ 'table', 'stock.lot.type',
+ default='stock.lot.type'.replace('.', '_'))
+
+ # Migration from 5.2: fill lot_required
+ if (table_h.table_exist(template_lot_type_table_name)
+ and table_h.table_exist(lot_type_table_name)):
+ table = cls.__table__()
+ template_lot_type = Table(template_lot_type_table_name)
+ lot_type = Table(lot_type_table_name)
+
+ cursor_select = connection.cursor()
+ cursor_select.execute(*template_lot_type.select(
+ template_lot_type.template,
+ distinct_on=template_lot_type.template))
+ for template_id, in cursor_select:
+ cursor.execute(*template_lot_type
+ .join(lot_type,
+ condition=template_lot_type.type == lot_type.id)
+ .select(
+ lot_type.code,
+ where=template_lot_type.template == template_id))
+ value = cls.lot_required.sql_format([t for t, in cursor])
+ cursor.execute(*table.update(
+ [table.lot_required], [value],
+ where=table.id == template_id))
+ table_h.drop_table('product.template-stock.lot.type',
+ template_lot_type_table_name)
+ table_h.drop_table('stock.lot.type', lot_type_table_name)
+
+ @classmethod
+ def default_lot_sequence(cls, **pattern):
+ pool = Pool()
+ Configuration = pool.get('product.configuration')
+ sequence = Configuration(1).get_multivalue(
+ 'default_lot_sequence', **pattern)
+ return sequence.id if sequence else None
+
+
+class Product(metaclass=PoolMeta):
+ __name__ = 'product.product'
+
+ def lot_is_required(self, from_, to):
+ 'Is product lot required for move with "from_" and "to" location ?'
+ return any(l.type in (self.lot_required or []) for l in [from_, to])
diff --git a/modules/stock_lot/product.xml b/modules/stock_lot/product.xml
new file mode 100644
index 0000000000..e36d47b573
--- /dev/null
+++ b/modules/stock_lot/product.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+ product.configuration
+
+ product_configuration_form
+
+
+
+ product.template
+
+ template_form
+
+
+
diff --git a/modules/stock_lot/setup.py b/modules/stock_lot/setup.py
new file mode 100755
index 0000000000..bd18b0ebfe
--- /dev/null
+++ b/modules/stock_lot/setup.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_lot'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = ['python-sql']
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [get_require_version('proteus'), 'python-dateutil']
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module for lot of products',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_lot',
+ },
+ keywords='tryton stock lot',
+ package_dir={'trytond.modules.stock_lot': '.'},
+ packages=(
+ ['trytond.modules.stock_lot']
+ + ['trytond.modules.stock_lot.%s' % p for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_lot': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'Intended Audience :: Manufacturing',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_lot = trytond.modules.stock_lot
+ """,
+ )
diff --git a/modules/stock_lot/stock.py b/modules/stock_lot/stock.py
new file mode 100644
index 0000000000..11b35c179d
--- /dev/null
+++ b/modules/stock_lot/stock.py
@@ -0,0 +1,819 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import datetime
+from copy import copy
+from functools import wraps
+
+from sql import Column
+from sql.functions import CharLength
+
+from trytond.i18n import gettext
+from trytond.model import Index, Model, ModelSQL, ModelView, fields
+from trytond.model.exceptions import (
+ AccessError, RequiredValidationError, ValidationError)
+from trytond.modules.stock import StockMixin
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Bool, Eval, Len
+from trytond.tools import grouped_slice
+from trytond.transaction import Transaction
+from trytond.wizard import Button, StateTransition, StateView, Wizard
+
+
+def check_no_move(func):
+ def find_moves(cls, records, state=None):
+ pool = Pool()
+ Move = pool.get('stock.move')
+ for sub_records in grouped_slice(records):
+ domain = [
+ ('lot', 'in', [r.id for r in sub_records])
+ ]
+ if state:
+ domain.append(('state', '=', state))
+ moves = Move.search(domain, limit=1, order=[])
+ if moves:
+ return True
+ return False
+
+ @wraps(func)
+ def decorator(cls, *args):
+ transaction = Transaction()
+ if (transaction.user != 0
+ and transaction.context.get('_check_access')):
+ actions = iter(args)
+ for records, values in zip(actions, actions):
+ for field, state, error in cls._modify_no_move:
+ if field in values:
+ if find_moves(cls, records, state):
+ raise AccessError(gettext(error))
+ # No moves for those records
+ break
+ func(cls, *args)
+ return decorator
+
+
+class LotMixin:
+ __slots__ = ()
+ number = fields.Char(
+ "Number", required=True,
+ states={
+ 'required': ~Eval('has_sequence') | (Eval('id', -1) >= 0),
+ })
+ product = fields.Many2One('product.product', 'Product', required=True)
+ has_sequence = fields.Function(
+ fields.Boolean("Has Sequence"), 'on_change_with_has_sequence')
+
+ @classmethod
+ def __setup__(cls):
+ cls.number.search_unaccented = False
+ super().__setup__()
+
+ @fields.depends('product')
+ def on_change_with_has_sequence(self, name=None):
+ if self.product:
+ return bool(self.product.lot_sequence)
+
+
+class Lot(ModelSQL, ModelView, LotMixin, StockMixin):
+ "Stock Lot"
+ __name__ = 'stock.lot'
+ _rec_name = 'number'
+
+ quantity = fields.Function(fields.Float('Quantity'), 'get_quantity',
+ searcher='search_quantity')
+ forecast_quantity = fields.Function(fields.Float('Forecast Quantity'),
+ 'get_quantity', searcher='search_quantity')
+ default_uom = fields.Function(
+ fields.Many2One('product.uom', "Default UOM"),
+ 'on_change_with_default_uom')
+ default_uom_digits = fields.Function(fields.Integer("Default Unit Digits"),
+ 'on_change_with_default_uom_digits')
+
+ @classmethod
+ def __setup__(cls):
+ super(Lot, cls).__setup__()
+ cls._modify_no_move = [
+ ('product', None, 'stock_lot.msg_change_product'),
+ ]
+ cls._buttons.update({
+ 'upward_traces': {},
+ 'downward_traces': {},
+ })
+
+ @classmethod
+ def order_number(cls, tables):
+ table, _ = tables[None]
+ return [CharLength(table.number), table.number]
+
+ @classmethod
+ def get_quantity(cls, lots, name):
+ location_ids = Transaction().context.get('locations')
+ product_ids = list(set(l.product.id for l in lots))
+ quantities = {}
+ for product_ids in grouped_slice(product_ids):
+ quantities.update(cls._get_quantity(lots, name, location_ids,
+ grouping=('product', 'lot',),
+ grouping_filter=(list(product_ids),)))
+ return quantities
+
+ @classmethod
+ def search_quantity(cls, name, domain=None):
+ location_ids = Transaction().context.get('locations')
+ return cls._search_quantity(name, location_ids, domain,
+ grouping=('product', 'lot'))
+
+ @fields.depends('product')
+ def on_change_with_default_uom(self, name=None):
+ if self.product:
+ return self.product.default_uom.id
+
+ @fields.depends('product')
+ def on_change_with_default_uom_digits(self, name=None):
+ if self.product:
+ return self.product.default_uom.digits
+
+ @classmethod
+ def create(cls, vlist):
+ vlist = [v.copy() for v in vlist]
+ for values in vlist:
+ if not values.get('number'):
+ values['number'] = cls._new_number(values)
+ return super().create(vlist)
+
+ @classmethod
+ def _new_number(cls, values):
+ pool = Pool()
+ Product = pool.get('product.product')
+ if values.get('product'):
+ product = Product(values['product'])
+ if product.lot_sequence:
+ return product.lot_sequence.get()
+
+ @classmethod
+ @check_no_move
+ def write(cls, *args):
+ super(Lot, cls).write(*args)
+
+ @classmethod
+ @ModelView.button_action('stock_lot.act_lot_trace_upward_relate')
+ def upward_traces(cls, lots):
+ pass
+
+ @classmethod
+ @ModelView.button_action('stock_lot.act_lot_trace_downward_relate')
+ def downward_traces(cls, lots):
+ pass
+
+
+class LotTrace(ModelSQL, ModelView):
+ "Lot Trace"
+ __name__ = 'stock.lot.trace'
+
+ product = fields.Many2One(
+ 'product.product', "Product",
+ context={
+ 'company': Eval('company', -1),
+ },
+ depends=['company'])
+ lot = fields.Many2One('stock.lot', "Lot")
+
+ quantity = fields.Float("Quantity", digits='unit')
+ unit = fields.Many2One('product.uom', "Unit")
+
+ company = fields.Many2One('company.company', "Company")
+ date = fields.Date("Date")
+ shipment = fields.Reference("Shipment", 'get_shipments')
+ document = fields.Function(
+ fields.Reference("Document", 'get_documents'), 'get_document')
+
+ upward_traces = fields.Function(
+ fields.Many2Many(
+ 'stock.lot.trace', None, None, "Upward Traces"),
+ 'get_upward_traces')
+ downward_traces = fields.Function(
+ fields.Many2Many(
+ 'stock.lot.trace', None, None, "Downward Traces"),
+ 'get_downward_traces')
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls._order.insert(0, ('date', 'ASC'))
+
+ @classmethod
+ def table_query(cls):
+ pool = Pool()
+ Move = pool.get('stock.move')
+ move = Move.__table__()
+ return (
+ move.select(
+ *cls._columns(move),
+ where=move.state == 'done'))
+
+ @classmethod
+ def _columns(cls, move):
+ return [
+ move.id.as_('id'),
+ move.create_uid.as_('create_uid'),
+ move.create_date.as_('create_date'),
+ move.write_uid.as_('write_uid'),
+ move.write_date.as_('write_date'),
+ move.product.as_('product'),
+ move.lot.as_('lot'),
+ move.quantity.as_('quantity'),
+ move.uom.as_('unit'),
+ move.company.as_('company'),
+ move.effective_date.as_('date'),
+ move.shipment.as_('shipment'),
+ ]
+
+ def get_rec_name(self, name):
+ return self.document.rec_name if self.document else str(self.id)
+
+ @classmethod
+ def get_shipments(cls):
+ pool = Pool()
+ Move = pool.get('stock.move')
+ return Move.get_shipment()
+
+ @classmethod
+ def get_documents(cls):
+ return cls.get_shipments()
+
+ def get_document(self, name):
+ if self.shipment:
+ return str(self.shipment)
+
+ @classmethod
+ def _is_trace_move(cls, move):
+ return move.state == 'done'
+
+ @classmethod
+ def _trace_move_order_key(cls, move):
+ return (move.effective_date,)
+
+ def get_upward_traces(self, name):
+ return list(map(int, sorted(filter(
+ self._is_trace_move, self._get_upward_traces()),
+ key=self._trace_move_order_key)))
+
+ def _get_upward_traces(self):
+ return set()
+
+ def get_downward_traces(self, name):
+ return list(map(int, sorted(filter(
+ self._is_trace_move, self._get_downward_traces()),
+ key=self._trace_move_order_key)))
+
+ def _get_downward_traces(self):
+ return set()
+
+
+class LotByLocationContext(ModelView):
+ 'Lot by Location'
+ __name__ = 'stock.lots_by_location.context'
+ forecast_date = fields.Date(
+ 'At Date', help=('Allow to compute expected '
+ 'stock quantities for this date.\n'
+ '* An empty value is an infinite date in the future.\n'
+ '* A date in the past will provide historical values.'))
+ stock_date_end = fields.Function(fields.Date('At Date'),
+ 'on_change_with_stock_date_end')
+
+ @staticmethod
+ def default_forecast_date():
+ Date = Pool().get('ir.date')
+ return Date.today()
+
+ @fields.depends('forecast_date')
+ def on_change_with_stock_date_end(self, name=None):
+ if self.forecast_date is None:
+ return datetime.date.max
+ return self.forecast_date
+
+
+class LotsByLocations(ModelSQL, ModelView):
+ "Lots by Locations"
+ __name__ = 'stock.lots_by_locations'
+
+ lot = fields.Many2One('stock.lot', "Lot")
+ product = fields.Many2One('product.product', "Product")
+ quantity = fields.Function(
+ fields.Float(
+ "Quantity", digits=(16, Eval('default_uom_digits', 2))),
+ 'get_lot', searcher='search_lot')
+ forecast_quantity = fields.Function(
+ fields.Float(
+ "Forecast Quantity", digits=(16, Eval('default_uom_digits', 2))),
+ 'get_lot', searcher='search_lot')
+ default_uom = fields.Function(
+ fields.Many2One('product.uom', "Default UOM"),
+ 'get_lot', searcher='search_lot')
+ default_uom_digits = fields.Function(
+ fields.Integer("Default UOM Digits"), 'get_lot')
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls._order.insert(0, ('lot', 'ASC'))
+ cls._order.insert(1, ('product', 'ASC'))
+
+ @classmethod
+ def table_query(cls):
+ pool = Pool()
+ Lot = pool.get('stock.lot')
+ lot = Lot.__table__()
+ columns = []
+ for fname, field in cls._fields.items():
+ if not hasattr(field, 'set'):
+ if (isinstance(field, fields.Many2One)
+ and field.get_target() == Lot):
+ column = Column(lot, 'id')
+ else:
+ column = Column(lot, fname)
+ columns.append(column.as_(fname))
+ return lot.select(*columns)
+
+ def get_rec_name(self, name):
+ return self.lot.rec_name
+
+ @classmethod
+ def search_rec_name(cls, name, clause):
+ return [('lot.rec_name',) + tuple(clause[1:])]
+
+ def get_lot(self, name):
+ value = getattr(self.lot, name)
+ if isinstance(value, Model):
+ value = value.id
+ return value
+
+ @classmethod
+ def search_lot(cls, name, clause):
+ nested = clause[0][len(name):]
+ return [('lot.' + name + nested, *clause[1:])]
+
+
+class LotByWarehouseContext(LotByLocationContext):
+ "Lot by Warehouse"
+ __name__ = 'stock.lots_by_warehouse.context'
+ warehouse = fields.Many2One(
+ 'stock.location', "Warehouse", required=True,
+ domain=[
+ ('type', '=', 'warehouse'),
+ ],
+ )
+ locations = fields.Function(
+ fields.Many2Many('stock.location', None, None, "Locations"),
+ 'on_change_with_locations')
+
+ @classmethod
+ def default_warehouse(cls):
+ return Pool().get('stock.location').get_default_warehouse()
+
+ @fields.depends('warehouse')
+ def on_change_with_locations(self, name=None):
+ locations = []
+ if self.warehouse:
+ locations.append(self.warehouse.id)
+ return locations
+
+
+class Location(metaclass=PoolMeta):
+ __name__ = 'stock.location'
+
+ @classmethod
+ def _get_quantity_grouping(cls):
+ pool = Pool()
+ Lot = pool.get('stock.lot')
+ context = Transaction().context
+ grouping, grouping_filter, key = super()._get_quantity_grouping()
+ if context.get('lot') is not None:
+ try:
+ lot, = Lot.search([('id', '=', context['lot'])])
+ except ValueError:
+ pass
+ else:
+ grouping = ('product', 'lot',)
+ grouping_filter = ([lot.product.id], [lot.id])
+ key = (lot.product.id, lot.id)
+ return grouping, grouping_filter, key
+
+
+class Move(metaclass=PoolMeta):
+ __name__ = 'stock.move'
+ lot = fields.Many2One('stock.lot', 'Lot',
+ domain=[
+ ('product', '=', Eval('product')),
+ ],
+ states={
+ 'readonly': Eval('state').in_(['cancelled', 'done']),
+ })
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls._buttons.update({
+ 'add_lots_wizard': {
+ 'invisible': ~Eval('state').in_(['draft', 'assigned']),
+ 'readonly': Bool(Eval('lot')),
+ 'depends': ['lot', 'state'],
+ },
+ })
+
+ @classmethod
+ @ModelView.button_action('stock_lot.wizard_move_add_lots')
+ def add_lots_wizard(cls, moves):
+ pass
+
+ def check_lot(self):
+ "Check if lot is required"
+ if (self.state == 'done'
+ and self.internal_quantity
+ and not self.lot
+ and self.product.lot_is_required(
+ self.from_location, self.to_location)):
+ raise RequiredValidationError(
+ gettext('stock_lot.msg_lot_required',
+ product=self.product.rec_name))
+
+ @classmethod
+ def validate(cls, moves):
+ super(Move, cls).validate(moves)
+ for move in moves:
+ move.check_lot()
+
+ @classmethod
+ def assign_try(cls, moves, with_childs=True, grouping=('product',)):
+ if 'lot' not in grouping:
+ moves_with_lot, moves_without_lot = [], []
+ for move in moves:
+ if move.lot:
+ moves_with_lot.append(move)
+ else:
+ moves_without_lot.append(move)
+ success = super().assign_try(
+ moves_with_lot, with_childs, grouping=grouping + ('lot',))
+ success &= super().assign_try(
+ moves_without_lot, with_childs, grouping=grouping)
+ else:
+ success = super().assign_try(moves, with_childs, grouping)
+ return success
+
+
+class MoveAddLots(Wizard):
+ "Add Lots"
+ __name__ = 'stock.move.add.lots'
+ start = StateView('stock.move.add.lots.start',
+ 'stock_lot.move_add_lots_start_view_form', [
+ Button("Cancel", 'end', 'tryton-cancel'),
+ Button("Add", 'add', 'tryton-ok', default=True),
+ ])
+ add = StateTransition()
+
+ def default_start(self, fields):
+ default = {}
+ if 'product' in fields:
+ default['product'] = self.record.product.id
+ if 'quantity' in fields:
+ default['quantity'] = self.record.quantity
+ if 'unit' in fields:
+ default['unit'] = self.record.uom.id
+ return default
+
+ def transition_add(self):
+ pool = Pool()
+ Lang = pool.get('ir.lang')
+ Lot = pool.get('stock.lot')
+ lang = Lang.get()
+ quantity_remaining = self.start.on_change_with_quantity_remaining()
+ if quantity_remaining < 0:
+ digits = self.record.uom.digits
+ move_quantity = self.record.quantity
+ lot_quantity = self.record.quantity - quantity_remaining
+ raise ValidationError(gettext(
+ 'stock_lot.msg_move_add_lot_quantity',
+ lot_quantity=lang.format_number(lot_quantity, digits),
+ move_quantity=lang.format_number(move_quantity, digits)))
+ lots = []
+ for line in self.start.lots:
+ lot = line.get_lot(self.record)
+ lots.append(lot)
+ Lot.save(lots)
+ if quantity_remaining:
+ self.record.quantity = quantity_remaining
+ self.record.save()
+ for i, (line, lot) in enumerate(zip(self.start.lots, lots)):
+ if not i and not quantity_remaining:
+ self.record.quantity = line.quantity
+ self.record.lot = lot
+ self.record.save()
+ else:
+ with Transaction().set_context(_stock_move_split=True):
+ self.model.copy([self.record], {
+ 'quantity': line.quantity,
+ 'lot': lot.id,
+ })
+ return 'end'
+
+
+class MoveAddLotsStart(ModelView):
+ "Add Lots"
+ __name__ = 'stock.move.add.lots.start'
+
+ product = fields.Many2One('product.product', "Product", readonly=True)
+ quantity = fields.Float("Quantity", digits='unit', readonly=True)
+ unit = fields.Many2One('product.uom', "Unit", readonly=True)
+ quantity_remaining = fields.Function(
+ fields.Float("Quantity Remaining", digits='unit'),
+ 'on_change_with_quantity_remaining')
+
+ lots = fields.One2Many(
+ 'stock.move.add.lots.start.lot', 'parent', "Lots",
+ domain=[
+ ('product', '=', Eval('product', -1)),
+ ],
+ states={
+ 'readonly': ~Eval('quantity_remaining', 0),
+ })
+
+ duplicate_lot_number = fields.Integer(
+ "Duplicate Lot Number",
+ states={
+ 'invisible': Len(Eval('lots')) != 1,
+ },
+ help="The number of times the lot must be duplicated.")
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls._buttons.update(
+ duplicate_lot={
+ 'invisible': Len(Eval('lots')) != 1,
+ 'readonly': (~Eval('duplicate_lot_number')
+ | (Eval('duplicate_lot_number', 0) <= 0)),
+ 'depends': ['lots', 'duplicate_lot_number'],
+ },
+ )
+
+ @fields.depends('quantity', 'lots', 'unit')
+ def on_change_with_quantity_remaining(self, name=None):
+ if self.quantity is not None:
+ quantity = self.quantity
+ if self.lots:
+ for lot in self.lots:
+ quantity -= getattr(lot, 'quantity', 0) or 0
+ if self.unit:
+ quantity = self.unit.round(quantity)
+ return quantity
+
+ @ModelView.button_change(
+ 'lots', 'duplicate_lot_number',
+ methods=['on_change_with_quantity_remaining'])
+ def duplicate_lot(self):
+ lots = list(self.lots)
+ template, = self.lots
+ for i in range(self.duplicate_lot_number):
+ lot = copy(template)
+ lot._id = None
+ lots.append(lot)
+ self.lots = lots
+ self.quantity_remaining = self.on_change_with_quantity_remaining()
+
+
+class MoveAddLotsStartLot(ModelView, LotMixin):
+ "Add Lots"
+ __name__ = 'stock.move.add.lots.start.lot'
+
+ parent = fields.Many2One('stock.move.add.lots.start', "Parent")
+ quantity = fields.Float("Quantity", digits='quantity_unit', required=True)
+ quantity_unit = fields.Function(
+ fields.Many2One('product.uom', "Unit"), 'on_change_with_quantity_unit')
+
+ @fields.depends(
+ 'parent', '_parent_parent.quantity_remaining')
+ def on_change_parent(self):
+ if (self.parent
+ and self.parent.quantity_remaining is not None):
+ self.quantity = self.parent.quantity_remaining
+
+ @fields.depends('parent', '_parent_parent.unit')
+ def on_change_with_quantity_unit(self, name=None):
+ if self.parent and self.parent.unit:
+ return self.parent.unit.id
+
+ @fields.depends('number', 'product', methods=['_set_lot_values'])
+ def on_change_number(self):
+ pool = Pool()
+ Lot = pool.get('stock.lot')
+ if self.number and self.product:
+ lots = Lot.search([
+ ('number', '=', self.number),
+ ('product', '=', self.product.id),
+ ])
+ if len(lots) == 1:
+ lot, = lots
+ self._set_lot_values(lot)
+
+ def _set_lot_values(self, lot):
+ pass
+
+ def get_lot(self, move):
+ pool = Pool()
+ Lot = pool.get('stock.lot')
+ values = self._get_lot_values(move)
+ lots = Lot.search(
+ [(k, '=', v) for k, v in values.items()],
+ limit=1)
+ if lots:
+ lot, = lots
+ else:
+ lot = Lot()
+ for k, v in values.items():
+ setattr(lot, k, v)
+ return lot
+
+ def _get_lot_values(self, move):
+ return {
+ 'number': self.number,
+ 'product': move.product,
+ }
+
+
+class ShipmentIn(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in'
+
+ def _get_inventory_move(self, incoming_move):
+ move = super()._get_inventory_move(incoming_move)
+ if move and incoming_move.lot:
+ move.lot = incoming_move.lot
+ return move
+
+
+class ShipmentOut(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out'
+
+ def _get_inventory_move(self, outgoing_move):
+ move = super()._get_inventory_move(outgoing_move)
+ if move and outgoing_move.lot:
+ move.lot = outgoing_move.lot
+ return move
+
+ def _sync_move_key(self, move):
+ return super()._sync_move_key(move) + (('lot', move.lot),)
+
+
+class ShipmentOutReturn(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out.return'
+
+ def _get_inventory_move(self, incoming_move):
+ move = super()._get_inventory_move(incoming_move)
+ if move and incoming_move.lot:
+ move.lot = incoming_move.lot
+ return move
+
+
+class ShipmentInternal(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.internal'
+
+ def _sync_move_key(self, move):
+ return super()._sync_move_key(move) + (('lot', move.lot),)
+
+
+class ShipmentDrop(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.drop'
+
+ def _sync_move_key(self, move):
+ return super()._sync_move_key(move) + (('lot', move.lot),)
+
+
+class Period(metaclass=PoolMeta):
+ __name__ = 'stock.period'
+ lot_caches = fields.One2Many('stock.period.cache.lot', 'period',
+ 'Lot Caches', readonly=True)
+
+ @classmethod
+ def groupings(cls):
+ return super(Period, cls).groupings() + [('product', 'lot')]
+
+ @classmethod
+ def get_cache(cls, grouping):
+ pool = Pool()
+ Cache = super(Period, cls).get_cache(grouping)
+ if grouping == ('product', 'lot'):
+ return pool.get('stock.period.cache.lot')
+ return Cache
+
+
+class PeriodCacheLot(ModelSQL, ModelView):
+ '''
+ Stock Period Cache per Lot
+
+ It is used to store cached computation of stock quantities per lot.
+ '''
+ __name__ = 'stock.period.cache.lot'
+ period = fields.Many2One(
+ 'stock.period', "Period",
+ required=True, readonly=True, ondelete='CASCADE')
+ location = fields.Many2One(
+ 'stock.location', "Location",
+ required=True, readonly=True, ondelete='CASCADE')
+ product = fields.Many2One('product.product', 'Product', required=True,
+ readonly=True, ondelete='CASCADE')
+ lot = fields.Many2One('stock.lot', 'Lot', readonly=True,
+ ondelete='CASCADE')
+ internal_quantity = fields.Float('Internal Quantity', readonly=True)
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ t = cls.__table__()
+ cls._sql_indexes.update({
+ Index(
+ t,
+ (t.period, Index.Equality()),
+ (t.product, Index.Equality()),
+ (t.lot, Index.Equality()),
+ include=[t.internal_quantity]),
+ Index(
+ t,
+ (t.location, Index.Equality())),
+ })
+
+
+class Inventory(metaclass=PoolMeta):
+ __name__ = 'stock.inventory'
+
+ @classmethod
+ def grouping(cls):
+ return super(Inventory, cls).grouping() + ('lot', )
+
+
+class InventoryLine(metaclass=PoolMeta):
+ __name__ = 'stock.inventory.line'
+ lot = fields.Many2One('stock.lot', 'Lot',
+ domain=[
+ ('product', '=', Eval('product')),
+ ],
+ states={
+ 'readonly': Eval('inventory_state') != 'draft',
+ })
+
+ @classmethod
+ def __setup__(cls):
+ super(InventoryLine, cls).__setup__()
+ cls._order.insert(1, ('lot', 'ASC'))
+
+ def get_rec_name(self, name):
+ rec_name = super(InventoryLine, self).get_rec_name(name)
+ if self.lot:
+ rec_name += ' - %s' % self.lot.rec_name
+ return rec_name
+
+ def get_move(self):
+ move = super(InventoryLine, self).get_move()
+ if move:
+ move.lot = self.lot
+ return move
+
+
+class InventoryCount(metaclass=PoolMeta):
+ __name__ = 'stock.inventory.count'
+
+ def default_quantity(self, fields):
+ pool = Pool()
+ Product = pool.get('product.product')
+ inventory = self.record
+ if isinstance(self.search.search, Product):
+ product = self.search.search
+ if product.lot_is_required(
+ inventory.location, inventory.location.lost_found_used):
+ raise RequiredValidationError(
+ gettext('stock_lot.msg_only_lot',
+ product=product.rec_name))
+ return super(InventoryCount, self).default_quantity(fields)
+
+ def get_line_domain(self, inventory):
+ pool = Pool()
+ Lot = pool.get('stock.lot')
+ domain = super(InventoryCount, self).get_line_domain(inventory)
+ if isinstance(self.search.search, Lot):
+ domain.append(('lot', '=', self.search.search.id))
+ return domain
+
+ def get_line_values(self, inventory):
+ pool = Pool()
+ Lot = pool.get('stock.lot')
+ values = super(InventoryCount, self).get_line_values(inventory)
+ if isinstance(self.search.search, Lot):
+ lot = self.search.search
+ values['product'] = lot.product.id
+ values['lot'] = lot.id
+ return values
+
+
+class InventoryCountSearch(metaclass=PoolMeta):
+ __name__ = 'stock.inventory.count.search'
+
+ @classmethod
+ def __setup__(cls):
+ super(InventoryCountSearch, cls).__setup__()
+ cls.search.selection.append(('stock.lot', "Lot"))
diff --git a/modules/stock_lot/stock.xml b/modules/stock_lot/stock.xml
new file mode 100644
index 0000000000..8d64362070
--- /dev/null
+++ b/modules/stock_lot/stock.xml
@@ -0,0 +1,368 @@
+
+
+
+
+
+ stock.lot
+ form
+ lot_form
+
+
+
+ stock.lot
+ tree
+ lot_tree
+
+
+
+ Lots
+ stock.lot
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ upward_traces
+ Upward Traces
+
+
+
+
+ downward_traces
+ Downward Traces
+
+
+
+
+ stock.lot.trace
+ tree
+ upward_traces
+ lot_trace_tree
+
+
+
+ stock.lot.trace
+ tree
+ downward_traces
+ lot_trace_tree
+
+
+
+ Upward Traces
+ stock.lot.trace
+
+
+
+
+
+
+
+
+ form_relate
+ stock.lot,-1
+
+
+
+
+ Downward Traces
+ stock.lot.trace
+
+
+
+
+
+
+
+
+ form_relate
+ stock.lot,-1
+
+
+
+
+ User in companies
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ stock.lots_by_location.context
+ form
+ lot_by_location_context_form
+
+
+
+ stock.lots_by_locations
+ tree
+ lots_by_locations_list
+
+
+
+ Lots by Locations
+ stock.lots_by_locations
+
+
+ stock.lots_by_location.context
+
+
+
+
+
+
+
+ tree_open
+ stock.location,-1
+
+
+
+ form_relate
+ stock.location,-1
+
+
+
+
+ stock.lots_by_warehouse.context
+
+ lot_by_warehouse_context_form
+
+
+
+ Lots By Warehouse
+ stock.lots_by_locations
+
+
+ stock.lots_by_warehouse.context
+
+
+
+
+
+
+
+ form_relate
+ product.template,-1
+
+
+
+ form_relate
+ product.product,-1
+
+
+
+
+ Locations Tree Quantity
+ stock.location
+
+
+ stock.lots_by_location.context
+
+
+
+
+
+
+
+ form_relate
+ stock.lot,-1
+
+
+
+
+ Locations List Quantity
+ stock.location
+
+
+ stock.lots_by_location.context
+
+
+
+
+
+
+
+ form_relate
+ stock.lot,-1
+
+
+
+
+ stock.move
+
+ move_form
+
+
+
+ stock.move
+
+ move_tree
+
+
+
+ stock.move
+
+ move_tree
+
+
+
+ stock.move
+
+ move_tree
+
+
+
+ add_lots_wizard
+ Add Lots
+
+
+
+
+ Add Lots
+ stock.move.add.lots
+ stock.move
+
+
+
+ stock.move.add.lots.start
+ form
+ stock_move_add_lots_start_form
+
+
+
+ stock.move.add.lots.start.lot
+ tree
+ stock_move_add_lots_start_lot_list
+
+
+
+ duplicate_lot
+ Duplicate Lot
+
+
+
+
+ stock.period.cache.lot
+ form
+ period_cache_lot_form
+
+
+ stock.period.cache.lot
+ tree
+ period_cache_lot_list
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ stock.inventory.line
+
+ inventory_line_form
+
+
+
+ stock.inventory.line
+
+ inventory_line_tree
+
+
+
+ stock.inventory.line
+
+ inventory_line_tree
+
+
+
+
diff --git a/modules/stock_lot/tests/__init__.py b/modules/stock_lot/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_lot/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_lot/tests/scenario_stock_lot_assign_try.rst b/modules/stock_lot/tests/scenario_stock_lot_assign_try.rst
new file mode 100644
index 0000000000..5e2f534caf
--- /dev/null
+++ b/modules/stock_lot/tests/scenario_stock_lot_assign_try.rst
@@ -0,0 +1,123 @@
+=================================
+Stock Lot Assign Request Scenario
+=================================
+
+Imports::
+
+ >>> import datetime
+ >>> from dateutil.relativedelta import relativedelta
+ >>> from decimal import Decimal
+
+ >>> from proteus import config, Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import (
+ ... create_company, get_company)
+ >>> today = datetime.date.today()
+
+Activate modules::
+
+ >>> config = activate_modules('stock_lot')
+ >>> Inventory = Model.get('stock.inventory')
+ >>> Location = Model.get('stock.location')
+ >>> Lot = Model.get('stock.lot')
+ >>> Party = Model.get('party.party')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> ProductUom = Model.get('product.uom')
+ >>> ShipmentOut = Model.get('stock.shipment.out')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create customer::
+
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+
+Create product::
+
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template.save()
+ >>> product, = template.products
+
+Create lot::
+
+ >>> lot = Lot()
+ >>> lot.number = 'LOT'
+ >>> lot.product = product
+ >>> lot.save()
+
+Get stock locations::
+
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+ >>> zone1 = Location(name='Zone1')
+ >>> zone1.parent = storage_loc
+ >>> zone1.type = 'storage'
+ >>> zone1.save()
+ >>> zone2, = zone1.duplicate(default={'name': 'Zone2'})
+
+Add product quantities on zones storage locations::
+
+ >>> inventory = Inventory()
+ >>> inventory.location = zone1
+ >>> inventory_line = inventory.lines.new(product=product)
+ >>> inventory_line.quantity = 100.0
+ >>> inventory_line.expected_quantity = 0.0
+ >>> inventory.click('confirm')
+ >>> inventory.state
+ 'done'
+ >>> inventory = Inventory()
+ >>> inventory.location = zone2
+ >>> inventory_line = inventory.lines.new()
+ >>> inventory_line.product = product
+ >>> inventory_line.lot = lot
+ >>> inventory_line.quantity = 100.0
+ >>> inventory_line.expected_quantity = 0.0
+ >>> inventory.click('confirm')
+ >>> inventory.state
+ 'done'
+
+Create shipment out::
+
+ >>> shipment = ShipmentOut()
+ >>> shipment.planned_date = today
+ >>> shipment.customer = customer
+ >>> shipment.warehouse = warehouse_loc
+ >>> shipment.company = company
+ >>> move = shipment.outgoing_moves.new()
+ >>> move.product = product
+ >>> move.uom = unit
+ >>> move.quantity = 10
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> move.company = company
+ >>> move.unit_price = Decimal('1')
+ >>> move.currency = company.currency
+ >>> shipment.click('wait')
+
+Request specific lot in stock assignation::
+
+ >>> move, = shipment.inventory_moves
+ >>> move.lot = lot
+ >>> move.save()
+
+Assign the shipment::
+
+ >>> shipment.click('assign_try')
+ True
+ >>> shipment.state
+ 'assigned'
+ >>> move, = shipment.inventory_moves
+ >>> move.from_location.name
+ 'Zone2'
diff --git a/modules/stock_lot/tests/scenario_stock_lot_move_add.rst b/modules/stock_lot/tests/scenario_stock_lot_move_add.rst
new file mode 100644
index 0000000000..683d1fafd9
--- /dev/null
+++ b/modules/stock_lot/tests/scenario_stock_lot_move_add.rst
@@ -0,0 +1,111 @@
+===========================
+Stock Lot Move Add Scenario
+===========================
+
+Imports::
+
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import (
+ ... create_company, get_company)
+
+Activate modules::
+
+ >>> config = activate_modules('stock_lot')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template.save()
+ >>> product, = template.products
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+
+Create a move::
+
+ >>> Move = Model.get('stock.move')
+ >>> move = Move()
+ >>> move.from_location = storage_loc
+ >>> move.to_location = customer_loc
+ >>> move.product = product
+ >>> move.quantity = 10
+ >>> move.unit_price = Decimal('20')
+ >>> move.currency = company.currency
+ >>> move.save()
+
+Create a lot::
+
+ >>> Lot = Model.get('stock.lot')
+ >>> lot2 = Lot(number='02', product=product)
+ >>> lot2.save()
+
+Add few lots::
+
+ >>> add_lots = Wizard('stock.move.add.lots', [move])
+ >>> add_lots.form.product== product
+ True
+ >>> add_lots.form.quantity
+ 10.0
+ >>> add_lots.form.unit == unit
+ True
+ >>> add_lots.form.quantity_remaining
+ 10.0
+
+ >>> lot = add_lots.form.lots.new()
+ >>> lot.quantity
+ 10.0
+ >>> lot.number = '01'
+ >>> lot.quantity = 2
+ >>> lot = add_lots.form.lots.new()
+ >>> lot.quantity
+ 8.0
+ >>> lot.number = '02'
+ >>> lot.quantity = 1
+
+ >>> add_lots.execute('add')
+
+Check moves::
+
+ >>> move, = Move.find([('lot.number', '=', '01')])
+ >>> move.quantity
+ 2.0
+ >>> move, = Move.find([('lot.number', '=', '02')])
+ >>> move.quantity
+ 1.0
+ >>> move.lot == lot2
+ True
+ >>> move, = Move.find([('lot', '=', None)])
+ >>> move.quantity
+ 7.0
+
+Add lot to remaining::
+
+ >>> add_lots = Wizard('stock.move.add.lots', [move])
+ >>> lot = add_lots.form.lots.new()
+ >>> lot.number = '03'
+ >>> add_lots.execute('add')
+
+ >>> len(Move.find([]))
+ 3
+ >>> move.lot.number
+ '03'
+ >>> move.quantity
+ 7.0
diff --git a/modules/stock_lot/tests/scenario_stock_lot_number.rst b/modules/stock_lot/tests/scenario_stock_lot_number.rst
new file mode 100644
index 0000000000..da55c438ff
--- /dev/null
+++ b/modules/stock_lot/tests/scenario_stock_lot_number.rst
@@ -0,0 +1,53 @@
+=========================
+Stock Lot Number Scenario
+=========================
+
+Imports::
+
+ >>> from decimal import Decimal
+ >>> from proteus import Model
+ >>> from trytond.tests.tools import activate_modules
+
+Activate modules::
+
+ >>> config = activate_modules('stock_lot')
+
+Create lot sequence::
+
+ >>> Sequence = Model.get('ir.sequence')
+ >>> SequenceType = Model.get('ir.sequence.type')
+ >>> sequence_type, = SequenceType.find(
+ ... [('name', '=', "Stock Lot")], limit=1)
+ >>> sequence = Sequence(name="Lot", sequence_type=sequence_type)
+ >>> sequence.save()
+
+Set default sequence::
+
+ >>> Configuration = Model.get('product.configuration')
+ >>> configuration = Configuration(1)
+ >>> configuration.default_lot_sequence = sequence
+ >>> configuration.save()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.lot_sequence == sequence
+ True
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.save()
+ >>> product, = template.products
+
+Create lot without number::
+
+ >>> Lot = Model.get('stock.lot')
+ >>> lot = Lot(product=product)
+ >>> lot.save()
+
+ >>> lot.number
+ '1'
diff --git a/modules/stock_lot/tests/scenario_stock_lot_shipment_out.rst b/modules/stock_lot/tests/scenario_stock_lot_shipment_out.rst
new file mode 100644
index 0000000000..c4ffcd1ae1
--- /dev/null
+++ b/modules/stock_lot/tests/scenario_stock_lot_shipment_out.rst
@@ -0,0 +1,130 @@
+===============================
+Stock Lot Shipment Out Scenario
+===============================
+
+Imports::
+
+ >>> import datetime
+ >>> from dateutil.relativedelta import relativedelta
+ >>> from decimal import Decimal
+ >>> from proteus import config, Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> today = datetime.date.today()
+
+Activate modules::
+
+ >>> config = activate_modules('stock_lot')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create customer::
+
+ >>> Party = Model.get('party.party')
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template.lot_required = ['storage']
+ >>> template.save()
+ >>> product, = template.products
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+
+Create Shipment Out::
+
+ >>> ShipmentOut = Model.get('stock.shipment.out')
+ >>> shipment_out = ShipmentOut()
+ >>> shipment_out.planned_date = today
+ >>> shipment_out.customer = customer
+ >>> shipment_out.warehouse = warehouse_loc
+ >>> shipment_out.company = company
+ >>> move = shipment_out.outgoing_moves.new()
+ >>> move.product = product
+ >>> move.uom =unit
+ >>> move.quantity = 10
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> move.company = company
+ >>> move.unit_price = Decimal('1')
+ >>> move.currency = company.currency
+ >>> shipment_out.save()
+
+Set the shipment state to waiting::
+
+ >>> shipment_out.click('wait')
+ >>> len(shipment_out.outgoing_moves)
+ 1
+ >>> len(shipment_out.inventory_moves)
+ 1
+
+Split inventory move::
+
+ >>> move, = shipment_out.inventory_moves
+ >>> move.quantity = 7
+ >>> move.save()
+ >>> with config.set_context(_stock_move_split=True):
+ ... _ = move.duplicate(default=dict(quantity=3))
+ >>> shipment_out.reload()
+
+Assign the shipment::
+
+ >>> shipment_out.click('assign_force')
+ >>> shipment_out.state
+ 'assigned'
+ >>> len(shipment_out.outgoing_moves)
+ 1
+
+Try to pick without lot::
+
+ >>> shipment_out.click('pick') # doctest: +IGNORE_EXCEPTION_DETAIL
+ Traceback (most recent call last):
+ ...
+ RequiredValidationError: ...
+
+Set 2 lots::
+
+ >>> Lot = Model.get('stock.lot')
+ >>> for i, move in enumerate(shipment_out.inventory_moves, start=1):
+ ... lot = Lot(number='%05i' % i, product=move.product)
+ ... lot.save()
+ ... move.lot = lot
+ >>> shipment_out.save()
+
+Pick the shipment::
+
+ >>> shipment_out.click('pick')
+ >>> shipment_out.state
+ 'picked'
+ >>> len(shipment_out.outgoing_moves)
+ 3
+ >>> sorted([m.quantity for m in shipment_out.outgoing_moves])
+ [0.0, 3.0, 7.0]
+ >>> lot_quantities = {}
+ >>> for move in shipment_out.outgoing_moves:
+ ... number = move.lot.number if move.lot else ''
+ ... quantity = lot_quantities.setdefault(number, 0)
+ ... lot_quantities[number] += move.quantity
+ >>> sorted(lot_quantities.items())
+ [('', 0.0), ('00001', 3.0), ('00002', 7.0)]
diff --git a/modules/stock_lot/tests/test_module.py b/modules/stock_lot/tests/test_module.py
new file mode 100644
index 0000000000..f6a7f73576
--- /dev/null
+++ b/modules/stock_lot/tests/test_module.py
@@ -0,0 +1,314 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import datetime
+from decimal import Decimal
+
+from dateutil.relativedelta import relativedelta
+
+from trytond.modules.company.tests import (
+ CompanyTestMixin, create_company, set_company)
+from trytond.pool import Pool
+from trytond.tests.test_tryton import ModuleTestCase, with_transaction
+from trytond.transaction import Transaction
+
+
+class StockLotTestCase(CompanyTestMixin, ModuleTestCase):
+ 'Test Stock Lot module'
+ module = 'stock_lot'
+
+ @with_transaction()
+ def test_products_by_location(self):
+ 'Test products_by_location'
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ Template = pool.get('product.template')
+ Product = pool.get('product.product')
+ Location = pool.get('stock.location')
+ Move = pool.get('stock.move')
+ Lot = pool.get('stock.lot')
+
+ kg, = Uom.search([('name', '=', 'Kilogram')])
+ g, = Uom.search([('name', '=', 'Gram')])
+ template, = Template.create([{
+ 'name': 'Test products_by_location',
+ 'type': 'goods',
+ 'default_uom': kg.id,
+ }])
+ product, = Product.create([{
+ 'template': template.id,
+ }])
+ supplier, = Location.search([('code', '=', 'SUP')])
+ customer, = Location.search([('code', '=', 'CUS')])
+ storage, = Location.search([('code', '=', 'STO')])
+ company = create_company()
+ currency = company.currency
+ with set_company(company):
+ lot1, lot2 = Lot.create([{
+ 'number': '1',
+ 'product': product.id,
+ }, {
+ 'number': '2',
+ 'product': product.id,
+ }])
+
+ moves = Move.create([{
+ 'product': product.id,
+ 'lot': lot1.id,
+ 'uom': kg.id,
+ 'quantity': 5,
+ 'from_location': supplier.id,
+ 'to_location': storage.id,
+ 'company': company.id,
+ 'unit_price': Decimal('1'),
+ 'currency': currency.id,
+ }, {
+ 'product': product.id,
+ 'lot': lot2.id,
+ 'uom': kg.id,
+ 'quantity': 10,
+ 'from_location': supplier.id,
+ 'to_location': storage.id,
+ 'company': company.id,
+ 'unit_price': Decimal('1'),
+ 'currency': currency.id,
+ }, {
+ 'product': product.id,
+ 'lot': lot2.id,
+ 'uom': kg.id,
+ 'quantity': 2,
+ 'from_location': storage.id,
+ 'to_location': customer.id,
+ 'company': company.id,
+ 'unit_price': Decimal('1'),
+ 'currency': currency.id,
+ }, {
+ 'product': product.id,
+ 'lot': None,
+ 'uom': kg.id,
+ 'quantity': 3,
+ 'from_location': supplier.id,
+ 'to_location': storage.id,
+ 'company': company.id,
+ 'unit_price': Decimal('1'),
+ 'currency': currency.id,
+ }])
+ Move.do(moves)
+
+ self.assertEqual(Product.products_by_location([storage.id],
+ grouping_filter=([product.id],)), {
+ (storage.id, product.id): 16,
+ })
+ self.assertEqual(Product.products_by_location([storage.id],
+ grouping=('product', 'lot',),
+ grouping_filter=([product.id],)), {
+ (storage.id, product.id, lot1.id): 5,
+ (storage.id, product.id, lot2.id): 8,
+ (storage.id, product.id, None): 3,
+ })
+ with Transaction().set_context(locations=[storage.id]):
+ lot1, lot2 = Lot.browse([lot1, lot2])
+ self.assertEqual(lot1.quantity, 5)
+ self.assertEqual(lot2.quantity, 8)
+
+ @with_transaction()
+ def test_period(self):
+ 'Test period'
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ Template = pool.get('product.template')
+ Product = pool.get('product.product')
+ Location = pool.get('stock.location')
+ Move = pool.get('stock.move')
+ Lot = pool.get('stock.lot')
+ Period = pool.get('stock.period')
+
+ unit, = Uom.search([('name', '=', 'Unit')])
+ template, = Template.create([{
+ 'name': 'Test period',
+ 'type': 'goods',
+ 'default_uom': unit.id,
+ }])
+ product, = Product.create([{
+ 'template': template.id,
+ }])
+ supplier, = Location.search([('code', '=', 'SUP')])
+ storage, = Location.search([('code', '=', 'STO')])
+ company = create_company()
+ currency = company.currency
+ with set_company(company):
+ lot1, lot2 = Lot.create([{
+ 'number': '1',
+ 'product': product.id,
+ }, {
+ 'number': '2',
+ 'product': product.id,
+ }])
+
+ today = datetime.date.today()
+
+ moves = Move.create([{
+ 'product': product.id,
+ 'lot': lot1.id,
+ 'uom': unit.id,
+ 'quantity': 5,
+ 'from_location': supplier.id,
+ 'to_location': storage.id,
+ 'planned_date': today - relativedelta(days=1),
+ 'effective_date': today - relativedelta(days=1),
+ 'company': company.id,
+ 'unit_price': Decimal('1'),
+ 'currency': currency.id,
+ }, {
+ 'product': product.id,
+ 'lot': lot2.id,
+ 'uom': unit.id,
+ 'quantity': 10,
+ 'from_location': supplier.id,
+ 'to_location': storage.id,
+ 'planned_date': today - relativedelta(days=1),
+ 'effective_date': today - relativedelta(days=1),
+ 'company': company.id,
+ 'unit_price': Decimal('1'),
+ 'currency': currency.id,
+ }, {
+ 'product': product.id,
+ 'lot': None,
+ 'uom': unit.id,
+ 'quantity': 3,
+ 'from_location': supplier.id,
+ 'to_location': storage.id,
+ 'planned_date': today - relativedelta(days=1),
+ 'effective_date': today - relativedelta(days=1),
+ 'company': company.id,
+ 'unit_price': Decimal('1'),
+ 'currency': currency.id,
+ }])
+ Move.do(moves)
+
+ period, = Period.create([{
+ 'date': today - relativedelta(days=1),
+ 'company': company.id,
+ }])
+ Period.close([period])
+ self.assertEqual(period.state, 'closed')
+
+ quantities = {
+ supplier: -18,
+ storage: 18,
+ }
+ for cache in period.caches:
+ self.assertEqual(cache.product, product)
+ self.assertEqual(cache.internal_quantity,
+ quantities[cache.location])
+
+ quantities = {
+ (supplier, lot1): -5,
+ (storage, lot1): 5,
+ (supplier, lot2): -10,
+ (storage, lot2): 10,
+ (supplier, None): -3,
+ (storage, None): 3,
+ }
+ for lot_cache in period.lot_caches:
+ self.assertEqual(lot_cache.product, product)
+ self.assertEqual(lot_cache.internal_quantity,
+ quantities[(lot_cache.location, lot_cache.lot)])
+
+ @with_transaction
+ def test_assign_try_with_lot(self):
+ "Test Move assign_try with lot"
+ pool = Pool()
+ Template = pool.get('product.template')
+ Product = pool.get('product.product')
+ Uom = pool.get('product.uom')
+ Location = pool.get('stock.location')
+ Move = pool.get('stock.move')
+ Lot = pool.get('stock.lot')
+
+ uom, = Uom.search([('name', '=', 'Meter')])
+ template = Template(
+ name="Product",
+ type='goods',
+ default_uom=uom,
+ )
+ template.save()
+ product = Product(template=template.id)
+ product.save()
+
+ supplier, = Location.search([('code', '=', 'SUP')])
+ storage, = Location.search([('code', '=', 'STO')])
+ customer, = Location.search([('code', '=', 'CUS')])
+
+ company = create_company()
+ with set_company(company):
+ lot1, lot2 = Lot.create([{
+ 'number': "1",
+ 'product': product.id,
+ }, {
+ 'number': "2",
+ 'product': product.id,
+ }])
+ moves = Move.create([{
+ 'product': product.id,
+ 'lot': lot1.id,
+ 'uom': uom.id,
+ 'quantity': 2,
+ 'from_location': supplier.id,
+ 'to_location': storage.id,
+ 'company': company.id,
+ 'unit_price': Decimal(1),
+ 'currency': company.currency.id,
+ }, {
+ 'product': product.id,
+ 'lot': lot2.id,
+ 'uom': uom.id,
+ 'quantity': 3,
+ 'from_location': supplier.id,
+ 'to_location': storage.id,
+ 'company': company.id,
+ 'unit_price': Decimal(1),
+ 'currency': company.currency.id,
+ }, {
+ 'product': product.id,
+ 'lot': None,
+ 'uom': uom.id,
+ 'quantity': 3,
+ 'from_location': supplier.id,
+ 'to_location': storage.id,
+ 'company': company.id,
+ 'unit_price': Decimal(1),
+ 'currency': company.currency.id,
+ }])
+ Move.do(moves)
+
+ move, = Move.create([{
+ 'product': product.id,
+ 'uom': uom.id,
+ 'quantity': 10,
+ 'from_location': storage.id,
+ 'to_location': customer.id,
+ 'company': company.id,
+ 'unit_price': Decimal(1),
+ 'currency': company.currency.id,
+ }])
+
+ self.assertFalse(
+ Move.assign_try([move], grouping=('product', 'lot')))
+ moves = Move.search([
+ ('product', '=', product.id),
+ ('from_location', '=', storage.id),
+ ('to_location', '=', customer.id),
+ ('company', '=', company.id),
+ ])
+ self.assertEqual(len(moves), 4)
+ self.assertEqual({
+ (m.lot, m.quantity, m.state) for m in moves}, {
+ (lot1, 2, 'assigned'),
+ (lot2, 3, 'assigned'),
+ (None, 1, 'assigned'),
+ (None, 4, 'draft'),
+ })
+
+
+del ModuleTestCase
diff --git a/modules/stock_lot/tests/test_scenario.py b/modules/stock_lot/tests/test_scenario.py
new file mode 100644
index 0000000000..dc1d23e7e5
--- /dev/null
+++ b/modules/stock_lot/tests/test_scenario.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import load_doc_tests
+
+
+def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_lot/tox.ini b/modules/stock_lot/tox.ini
new file mode 100644
index 0000000000..2c78a15a21
--- /dev/null
+++ b/modules/stock_lot/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_lot/* -m unittest discover -s tests
+ coverage report --include=./**/stock_lot/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_lot/tryton.cfg b/modules/stock_lot/tryton.cfg
new file mode 100644
index 0000000000..6afd3c6181
--- /dev/null
+++ b/modules/stock_lot/tryton.cfg
@@ -0,0 +1,13 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ product
+ stock
+extras_depend:
+ sale_supply_drop_shipment
+xml:
+ ir.xml
+ stock.xml
+ product.xml
+ message.xml
diff --git a/modules/stock_lot/view/inventory_line_form.xml b/modules/stock_lot/view/inventory_line_form.xml
new file mode 100644
index 0000000000..6882aa4ecc
--- /dev/null
+++ b/modules/stock_lot/view/inventory_line_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot/view/inventory_line_tree.xml b/modules/stock_lot/view/inventory_line_tree.xml
new file mode 100644
index 0000000000..4f1ec7d31a
--- /dev/null
+++ b/modules/stock_lot/view/inventory_line_tree.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/stock_lot/view/lot_by_location_context_form.xml b/modules/stock_lot/view/lot_by_location_context_form.xml
new file mode 100644
index 0000000000..09aede248e
--- /dev/null
+++ b/modules/stock_lot/view/lot_by_location_context_form.xml
@@ -0,0 +1,8 @@
+
+
+
diff --git a/modules/stock_lot/view/lot_by_warehouse_context_form.xml b/modules/stock_lot/view/lot_by_warehouse_context_form.xml
new file mode 100644
index 0000000000..e352324fcd
--- /dev/null
+++ b/modules/stock_lot/view/lot_by_warehouse_context_form.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot/view/lot_form.xml b/modules/stock_lot/view/lot_form.xml
new file mode 100644
index 0000000000..a71a859cfb
--- /dev/null
+++ b/modules/stock_lot/view/lot_form.xml
@@ -0,0 +1,14 @@
+
+
+
diff --git a/modules/stock_lot/view/lot_trace_tree.xml b/modules/stock_lot/view/lot_trace_tree.xml
new file mode 100644
index 0000000000..a8b89d709e
--- /dev/null
+++ b/modules/stock_lot/view/lot_trace_tree.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot/view/lot_tree.xml b/modules/stock_lot/view/lot_tree.xml
new file mode 100644
index 0000000000..4f893a670f
--- /dev/null
+++ b/modules/stock_lot/view/lot_tree.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
diff --git a/modules/stock_lot/view/lots_by_locations_list.xml b/modules/stock_lot/view/lots_by_locations_list.xml
new file mode 100644
index 0000000000..8cba9a32af
--- /dev/null
+++ b/modules/stock_lot/view/lots_by_locations_list.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot/view/move_form.xml b/modules/stock_lot/view/move_form.xml
new file mode 100644
index 0000000000..0e1169dea6
--- /dev/null
+++ b/modules/stock_lot/view/move_form.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot/view/move_tree.xml b/modules/stock_lot/view/move_tree.xml
new file mode 100644
index 0000000000..475dd4c595
--- /dev/null
+++ b/modules/stock_lot/view/move_tree.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot/view/period_cache_lot_form.xml b/modules/stock_lot/view/period_cache_lot_form.xml
new file mode 100644
index 0000000000..4e532bfa27
--- /dev/null
+++ b/modules/stock_lot/view/period_cache_lot_form.xml
@@ -0,0 +1,15 @@
+
+
+
diff --git a/modules/stock_lot/view/period_cache_lot_list.xml b/modules/stock_lot/view/period_cache_lot_list.xml
new file mode 100644
index 0000000000..9bb28c59c4
--- /dev/null
+++ b/modules/stock_lot/view/period_cache_lot_list.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot/view/product_configuration_form.xml b/modules/stock_lot/view/product_configuration_form.xml
new file mode 100644
index 0000000000..4a1d0d2778
--- /dev/null
+++ b/modules/stock_lot/view/product_configuration_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot/view/stock_move_add_lots_start_form.xml b/modules/stock_lot/view/stock_move_add_lots_start_form.xml
new file mode 100644
index 0000000000..163932fa22
--- /dev/null
+++ b/modules/stock_lot/view/stock_move_add_lots_start_form.xml
@@ -0,0 +1,20 @@
+
+
+
diff --git a/modules/stock_lot/view/stock_move_add_lots_start_lot_list.xml b/modules/stock_lot/view/stock_move_add_lots_start_lot_list.xml
new file mode 100644
index 0000000000..ec98f00cda
--- /dev/null
+++ b/modules/stock_lot/view/stock_move_add_lots_start_lot_list.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot/view/template_form.xml b/modules/stock_lot/view/template_form.xml
new file mode 100644
index 0000000000..894baf1ec2
--- /dev/null
+++ b/modules/stock_lot/view/template_form.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot_sled/.drone.yml b/modules/stock_lot_sled/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_lot_sled/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_lot_sled/.flake8 b/modules/stock_lot_sled/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_lot_sled/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_lot_sled/.isort.cfg b/modules/stock_lot_sled/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_lot_sled/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_lot_sled/CHANGELOG b/modules/stock_lot_sled/CHANGELOG
new file mode 100644
index 0000000000..10a8e226d3
--- /dev/null
+++ b/modules/stock_lot_sled/CHANGELOG
@@ -0,0 +1,55 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+* Change shelf_life_delay into TimeDelta
+
+Version 4.2.0 - 2016-11-28
+* Bug fixes (see mercurial logs for details)
+
+Version 4.0.0 - 2016-05-02
+* Bug fixes (see mercurial logs for details)
+* Add Python3 support
+
+Version 3.8.0 - 2015-11-02
+* Bug fixes (see mercurial logs for details)
+* Add Shelf Life Delay
+
+Version 3.6.0 - 2015-04-20
+* Initial release
diff --git a/modules/stock_lot_sled/COPYRIGHT b/modules/stock_lot_sled/COPYRIGHT
new file mode 100644
index 0000000000..276b2c7518
--- /dev/null
+++ b/modules/stock_lot_sled/COPYRIGHT
@@ -0,0 +1,16 @@
+Copyright (C) 2014-2022 Cédric Krier.
+Copyright (C) 2014-2022 B2CK SPRL.
+Copyright (C) 2013-2015 NaN·tic
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_lot_sled/LICENSE b/modules/stock_lot_sled/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_lot_sled/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_lot_sled/MANIFEST.in b/modules/stock_lot_sled/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_lot_sled/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_lot_sled/README.rst b/modules/stock_lot_sled/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_lot_sled/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_lot_sled/__init__.py b/modules/stock_lot_sled/__init__.py
new file mode 100644
index 0000000000..b1582f7353
--- /dev/null
+++ b/modules/stock_lot_sled/__init__.py
@@ -0,0 +1,22 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import product, stock
+from .stock import LotSledMixin
+
+__all__ = ['LotSledMixin', 'register']
+
+
+def register():
+ Pool.register(
+ product.Template,
+ product.Product,
+ stock.Configuration,
+ stock.ConfigurationLotShelfLife,
+ stock.Lot,
+ stock.MoveAddLotsStartLot,
+ stock.Move,
+ stock.Period,
+ module='stock_lot_sled', type_='model')
diff --git a/modules/stock_lot_sled/doc/index.rst b/modules/stock_lot_sled/doc/index.rst
new file mode 100644
index 0000000000..cdca95f0da
--- /dev/null
+++ b/modules/stock_lot_sled/doc/index.rst
@@ -0,0 +1,13 @@
+Stock Lot Shelf Life Expiration Date
+####################################
+
+The stock_lot_sled module adds two fields on lot of products:
+
+ - Shelf Live Expiration Date
+ - Expiration Date
+
+And it defines on the product the default time for those fields and on the
+stock configuration the Shelf Live Delay.
+
+When the shelf life of a lot expires in less than the configured shelf life
+delay, it is no more used to compute the forecast quantity of the stock.
diff --git a/modules/stock_lot_sled/exceptions.py b/modules/stock_lot_sled/exceptions.py
new file mode 100644
index 0000000000..21498fa0b3
--- /dev/null
+++ b/modules/stock_lot_sled/exceptions.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.exceptions import UserError, UserWarning
+
+
+class LotExpiredError(UserError):
+ pass
+
+
+class LotExpiredWarning(UserWarning):
+ pass
diff --git a/modules/stock_lot_sled/locale/bg.po b/modules/stock_lot_sled/locale/bg.po
new file mode 100644
index 0000000000..a14bbfb301
--- /dev/null
+++ b/modules/stock_lot_sled/locale/bg.po
@@ -0,0 +1,257 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr "Крайна дата"
+
+#, fuzzy
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr "Крайна дата"
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr "Крайна дата"
+
+#, fuzzy
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr "Крайна дата"
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Крайна дата"
+
+#, fuzzy
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Крайна дата"
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Крайна дата"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Крайна дата"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Крайна дата"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Крайна дата"
+
+#, fuzzy
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr "В брой дни"
+
+#, fuzzy
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr "В брой дни"
+
+#, fuzzy
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr "В брой дни"
+
+#, fuzzy
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr "В брой дни"
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Stock Force Expiration"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "Няма"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "Задължителен"
+
+#, fuzzy
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "Няма"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "Задължителен"
+
+#, fuzzy
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "Няма"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "Задължителен"
+
+#, fuzzy
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "Няма"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "Задължителен"
+
+#, fuzzy
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "Няма"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "Задължителен"
+
+#, fuzzy
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Няма"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Задължителен"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "Няма"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "Задължителен"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Няма"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Задължителен"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/ca.po b/modules/stock_lot_sled/locale/ca.po
new file mode 100644
index 0000000000..bb3d237a45
--- /dev/null
+++ b/modules/stock_lot_sled/locale/ca.po
@@ -0,0 +1,233 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr "Estat caducitat"
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr "Temps a caducar"
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Estat vida útil"
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Temps vida útil"
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr "Estat caducitat"
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr "Temps a caducar"
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Estat vida útil"
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Temps vida útil"
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Retard de la vida útil"
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Retard de la vida útil"
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Data caducitat"
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Estat caducitat"
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Data fi vida útil"
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Estat vida útil"
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Data caducitat"
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Estat caducitat"
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Data fi vida útil"
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Estat vida útil"
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr "En nombre de dies."
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr "En nombre de dies."
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr "En nombre de dies."
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr "En nombre de dies."
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "El retard abans d'eliminar de les previsions."
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "El retard abans d'eliminar de les previsions."
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+"No podeu modificar les dates de caducitat del lot \"%(lot)s\" perquè "
+"s'utilitza en el moviment \"%(move)s\" d'un període tancat."
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+"No podeu processar el moviment \"%(move)s\" perquè el seu lot \"%(lot)s\" ha"
+" expirat."
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+"No podeu tancar períodes abans de l'expiració del lot \"%(lot)s\" "
+"(%(date)s)."
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Forçar caducitats a logística"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr "Configuració del retard de la vida útil"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "Cap"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "Obligatori"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "Cap"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "Obligatori"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "Cap"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "Obligatori"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "Cap"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "Obligatori"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "Cap"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "Obligatori"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Cap"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Obligatori"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "Cap"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "Obligatori"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Cap"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Obligatori"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr "Vida útil"
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr "Lot"
diff --git a/modules/stock_lot_sled/locale/cs.po b/modules/stock_lot_sled/locale/cs.po
new file mode 100644
index 0000000000..269646e458
--- /dev/null
+++ b/modules/stock_lot_sled/locale/cs.po
@@ -0,0 +1,227 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Stock Force Expiration"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/de.po b/modules/stock_lot_sled/locale/de.po
new file mode 100644
index 0000000000..c3deb20fa8
--- /dev/null
+++ b/modules/stock_lot_sled/locale/de.po
@@ -0,0 +1,235 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr "Verfallsstatus"
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr "Verfallsdauer"
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Mindesthaltbarkeitsstatus"
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Mindesthaltbarkeitsdauer"
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr "Verfallsstatus"
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr "Verfallsdauer"
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Mindesthaltbarkeitsstatus"
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Haltbarkeitsdauer"
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Aufschub Mindesthaltbarkeitsablauf"
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Aufschub Mindesthaltbarkeitsablauf"
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Verfallsdatum"
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Verfallsstatus"
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Mindesthaltbarkeitsdatum"
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Mindesthaltbarkeitsstatus"
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Verfallsdatum"
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Verfallsstatus"
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Mindesthaltbarkeitsdatum"
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Mindesthaltbarkeitsstatus"
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr "In Tagen."
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr "In Tagen."
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr "In Tagen."
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr "In Tagen."
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "Der Aufschub vor dem Entfernen aus der Bedarfsermittlung."
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "Der Aufschub vor dem Entfernen aus der Bedarfsermittlung."
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+"Das Verfallsdatum von Charge \"%(lot)s\" kann nicht verändert werden, weil "
+"sie in Warenbewegung \"%(move)s\" in einem geschlossenen "
+"Lagerbuchungszeitraum verwendet wird."
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+"Die Warenbewegung \"%(move)s\" kann nicht ausgeführt werden, weil die "
+"zugewiesene Charge \"%(lot)s\" abgelaufen ist."
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+"Lagerbuchungszeiträume können nicht vor Erreichen des "
+"Mindesthaltbarkeitsdatums der Charge \"%(lot)s\" (%(date)s) geschlossen "
+"werden."
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Lager Erzwingen bei Ablauf Mindesthaltbarkeit"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr "Einstellungen Lager Charge Mindesthaltbarkeit"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "Keiner"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr "Optional"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "Erforderlich"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "Keiner"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr "Optional"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "Erforderlich"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "Keiner"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr "Optional"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "Erforderlich"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "Keiner"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr "Optional"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "Erforderlich"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "Keiner"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr "Optional"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "Erforderlich"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Keiner"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Optional"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Erforderlich"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "Keiner"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr "Optional"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "Erforderlich"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Keiner"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Optional"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Erforderlich"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr "Mindesthaltbarkeit"
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr "Charge"
diff --git a/modules/stock_lot_sled/locale/es.po b/modules/stock_lot_sled/locale/es.po
new file mode 100644
index 0000000000..61531839e3
--- /dev/null
+++ b/modules/stock_lot_sled/locale/es.po
@@ -0,0 +1,233 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr "Estado caducidad"
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr "Tiempo a caducar"
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Estado vida útil"
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Tiempo vida útil"
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr "Estado caducidad"
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr "Tiempo a caducar"
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Estado vida útil"
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Tiempo vida útil"
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Retraso de la vida útil"
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Retraso de la vida útil"
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Fecha caducidad"
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Estado caducidad"
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Fecha fin vida útil"
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Estado vida útil"
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Fecha caducidad"
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Estado caducidad"
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Fecha fin vida útil"
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Estado vida útil"
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr "En número de días."
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr "En número de días."
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr "En número de días."
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr "En número de días."
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "El retraso antes de eliminar de las previsiones."
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "El retraso antes de eliminar de las previsiones."
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+"No puede modificar las fechas de caducidad del lote \"%(lot)s\" porque se "
+"utiliza en el movimento \"%(move)s\" en un periodo cerrado."
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+"No puede procesar el movimiento \"%(move)s\" porque su \"%(lot)s\" ha "
+"expirado."
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+"No puede cerrar periodos antes de la expiración del lote \"%(lot)s\" "
+"(%(date)s)."
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Forzar caducidades en logística"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr "Configuración del retraso de la vida útil"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "Ninguno"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "Obligatorio"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "Ninguno"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "Obligatorio"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "Ninguno"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "Obligatorio"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "Ninguno"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "Obligatorio"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "Ninguno"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "Obligatorio"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Ninguno"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Obligatorio"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "Ninguno"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "Obligatorio"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Ninguno"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Obligatorio"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr "Vida útil"
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr "Lote"
diff --git a/modules/stock_lot_sled/locale/es_419.po b/modules/stock_lot_sled/locale/es_419.po
new file mode 100644
index 0000000000..9d14297188
--- /dev/null
+++ b/modules/stock_lot_sled/locale/es_419.po
@@ -0,0 +1,233 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr "Estado de caducidad"
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr "Tiempo de caducidad"
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Estado de vida útil"
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Tiempo de vida útil"
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr "Estado de caducidad"
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr "Tiempo de caducidad"
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Estado de vida útil"
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Tiempo de vida útil"
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Fecha de caducidad"
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Estado de caducidad"
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Fecha de caducidad de vida útil"
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Estado de caducidad de vida útil"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Fecha de caducidad"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Estado de caducidad"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Fecha de caducidad de vida útil"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Estado de caducidad de vida útil"
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr ""
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "Requerido"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "Requerido"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "Requerido"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "Requerido"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "Requerido"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Requerido"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "Requerido"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Requerido"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/et.po b/modules/stock_lot_sled/locale/et.po
new file mode 100644
index 0000000000..2ad24606dc
--- /dev/null
+++ b/modules/stock_lot_sled/locale/et.po
@@ -0,0 +1,241 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr "Aegumise staatus"
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr "Aegumistähtaeg"
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr "Aegumise staatus"
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr "Aegumistähtaeg"
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Aegumistähtaeg"
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Aegumise staatus"
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Aegumistähtaeg"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Aegumise staatus"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Aegumistähtaeg"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Aegumise staatus"
+
+#, fuzzy
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr "Päevades"
+
+#, fuzzy
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr "Päevades"
+
+#, fuzzy
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr "Päevades"
+
+#, fuzzy
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr "Päevades"
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr ""
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "Mitte"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr "Valikuline"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "Nõutud"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "Mitte"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr "Valikuline"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "Nõutud"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "Mitte"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr "Valikuline"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "Nõutud"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "Mitte"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr "Valikuline"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "Nõutud"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "Mitte"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr "Valikuline"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "Nõutud"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Mitte"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Valikuline"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Nõutud"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "Mitte"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr "Valikuline"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "Nõutud"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Mitte"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Valikuline"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Nõutud"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/fa.po b/modules/stock_lot_sled/locale/fa.po
new file mode 100644
index 0000000000..9be7c7364d
--- /dev/null
+++ b/modules/stock_lot_sled/locale/fa.po
@@ -0,0 +1,246 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr "وضعیت انقضاء"
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr "زمان انقضاء"
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "وضعیت عمر مفید مصرف"
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "عمر مفید مصرف"
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr "وضعیت انقضاء"
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr "زمان انقضاء"
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "وضعیت عمر مفید مصرف"
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "عمر مفید مصرف"
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "عمر مفید تاخیر"
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "عمر مفید تاخیر"
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "تاریخ انقضاء"
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "وضعیت انقضاء"
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "عمر مفید تاریخ انقضاء"
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "وضعیت مفید تاریخ انقضاء"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "تاریخ انقضاء"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "وضعیت انقضاء"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "عمر مفید تاریخ انقضاء"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "وضعیت مفید تاریخ انقضاء"
+
+#, fuzzy
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr "در تعداد روزها"
+
+#, fuzzy
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr "در تعداد روزها"
+
+#, fuzzy
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr "در تعداد روزها"
+
+#, fuzzy
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr "در تعداد روزها"
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "تاخیر قبل از حذف از پیش بینی."
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "تاخیر قبل از حذف از پیش بینی."
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+"شما نمیتوانید تاریخ های انقضاء کالاهای: \"%s\" را تغییر دهید چونکه در "
+"جابجایی : \"%s\" در دوره بسته شده استفاده شده است."
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+"شما نمیتوانید جابجایی :\"%(move)s\" را پردازش کنید، چراکه تاریخ اجناس "
+":\"%(lot)s\" منقضی شده است."
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+"شما نمیتوانید دوره ها را قبل از انقضای اجناس :\"%(lot)s\" (%(date)s) ببندید."
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "تاریخ انقضاء موجودی"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr "پیکربندی موجودی ؛ عمرمفید مصرف"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "هیجکدام"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr "اختیاری"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "مورد نیاز"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "هیجکدام"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr "اختیاری"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "مورد نیاز"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "هیجکدام"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr "اختیاری"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "مورد نیاز"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "هیجکدام"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr "اختیاری"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "مورد نیاز"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "هیجکدام"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr "اختیاری"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "مورد نیاز"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "هیجکدام"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "اختیاری"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "مورد نیاز"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "هیجکدام"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr "اختیاری"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "مورد نیاز"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "هیجکدام"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "اختیاری"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "مورد نیاز"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr "عمر مفید مصرف"
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/fi.po b/modules/stock_lot_sled/locale/fi.po
new file mode 100644
index 0000000000..269646e458
--- /dev/null
+++ b/modules/stock_lot_sled/locale/fi.po
@@ -0,0 +1,227 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Stock Force Expiration"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/fr.po b/modules/stock_lot_sled/locale/fr.po
new file mode 100644
index 0000000000..4a011a7343
--- /dev/null
+++ b/modules/stock_lot_sled/locale/fr.po
@@ -0,0 +1,233 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr "État d'expiration"
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr "Délai d'expiration"
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "État de la durée limite d'utilisation optimale"
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Durée limite d'utilisation optimale"
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr "État d'expiration"
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr "Délai d'expiration"
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "État de la durée limite d'utilisation optimale"
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Durée limite d'utilisation optimale"
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Délai de durée limite d'utilisation optimale"
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Délai de durée limite d'utilisation optimale"
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Date d'expiration"
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "État d'expiration"
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Date limite d'utilisation optimale"
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "État de la date limite d'utilisation optimale"
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Date d'expiration"
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "État d'expiration"
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Date limite d'utilisation optimale"
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "État de la date limite d'utilisation optimale"
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr "En nombre de jours."
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr "En nombre de jours."
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr "En nombre de jours."
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr "En nombre de jours."
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "Le délai avant d'être retiré de la prévision."
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "Le délai avant d'être retiré de la prévision."
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+"Vous ne pouvez pas modifier les dates d'expiration du lot « %(lot)s » car il"
+" est utilisé sur un mouvement « %(move)s » d'une période clôturée."
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+"Vous ne pouvez pas traiter le mouvement « %(move)s » car son lot « %(lot)s »"
+" a expiré."
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+"Vous ne pouvez pas clôturer les périodes avant l'expiration du lot "
+"« %(lot)s » (%(date)s)."
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Force l'expiration des stocks"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr "Configuration de lot de stock Durée limite d'utilisation optimale"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "Aucune"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr "Optionnelle"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "Requise"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "Aucune"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr "Optionnelle"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "Requise"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "Aucune"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr "Optionnelle"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "Requis"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "Aucune"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr "Optionnel"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "Requis"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "Aucune"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr "Optionnelle"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "Requis"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Aucune"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Optionnelle"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Requis"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "Aucune"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr "Optionnelle"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "Requise"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Aucun"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Optionnel"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Requis"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr "Limite d'utilisation optimale"
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr "Lot"
diff --git a/modules/stock_lot_sled/locale/hu.po b/modules/stock_lot_sled/locale/hu.po
new file mode 100644
index 0000000000..70c5d0bfd0
--- /dev/null
+++ b/modules/stock_lot_sled/locale/hu.po
@@ -0,0 +1,256 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr "Lejárat dátuma"
+
+#, fuzzy
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr "Lejárat időpontja"
+
+#, fuzzy
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Raktáridő állapota"
+
+#, fuzzy
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Raktáridő"
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr "Lejárat dátuma"
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr "Lejárat időpontja"
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Raktáridő állapota"
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Raktáridő"
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Raktáridő várakozás időtartama"
+
+#, fuzzy
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Raktáridő várakozás időtartama"
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Lejárati dátuma"
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Lejárati állapot"
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Raktáridő lejárati dátum"
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Raktáridő lejárati dátum"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Lejárati dátuma"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Lejárat dátuma"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Raktáridő lejárati dátum"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Raktáridő lejárati dátum"
+
+#, fuzzy
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr "Napok száma"
+
+#, fuzzy
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr "Napok száma"
+
+#, fuzzy
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr "Napok száma"
+
+#, fuzzy
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr "Napok száma"
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+"A Charge \"%(lot)s\" lejárati dátuma nem módosítható, egy zárt raktár "
+"időszakban raktármozgás \"%(move)s\" van."
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Stock Force Expiration"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "Nincs"
+
+#, fuzzy
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr "Opcionális"
+
+#, fuzzy
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "Szükséges"
+
+#, fuzzy
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "Nincs"
+
+#, fuzzy
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr "Opcionális"
+
+#, fuzzy
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "Szükséges"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "Nincs"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr "Opcionális"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "Szükséges"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "Nincs"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr "Opcionális"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "Szükséges"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "Nincs"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr "Opcionális"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "Szükséges"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Nincs"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Opcionális"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Szükséges"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "Nincs"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr "Opcionális"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "Szükséges"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Nincs"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Opcionális"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Szükséges"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr "Raktár idő"
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/id.po b/modules/stock_lot_sled/locale/id.po
new file mode 100644
index 0000000000..a2b02fb465
--- /dev/null
+++ b/modules/stock_lot_sled/locale/id.po
@@ -0,0 +1,233 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr ""
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "Tidak ada"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr "Pilihan"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "Wajib"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "Tidak ada"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr "Pilihan"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "Wajib"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "Tidak ada"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr "Pilihan"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "Wajib"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "Tidak ada"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr "Pilihan"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "Wajib"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "Tidak ada"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr "Pilihan"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "Wajib"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Tidak ada"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Pilihan"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Wajib"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "Tidak ada"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr "Pilihan"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "Wajib"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Tidak ada"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Pilihan"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Wajib"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/it.po b/modules/stock_lot_sled/locale/it.po
new file mode 100644
index 0000000000..f3370f80cc
--- /dev/null
+++ b/modules/stock_lot_sled/locale/it.po
@@ -0,0 +1,243 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Stock Force Expiration"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "Nessuno"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "Obbligatorio"
+
+#, fuzzy
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "Nessuno"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "Obbligatorio"
+
+#, fuzzy
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "Nessuno"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "Obbligatorio"
+
+#, fuzzy
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "Nessuno"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "Obbligatorio"
+
+#, fuzzy
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "Nessuno"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "Obbligatorio"
+
+#, fuzzy
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Nessuno"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Obbligatorio"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "Nessuno"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "Obbligatorio"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Nessuno"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Obbligatorio"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr "Lotto"
diff --git a/modules/stock_lot_sled/locale/lo.po b/modules/stock_lot_sled/locale/lo.po
new file mode 100644
index 0000000000..353dd2a5ff
--- /dev/null
+++ b/modules/stock_lot_sled/locale/lo.po
@@ -0,0 +1,243 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Stock Force Expiration"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "ບໍ່ມີ"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "ຕ້ອງມີ"
+
+#, fuzzy
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "ບໍ່ມີ"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "ຕ້ອງມີ"
+
+#, fuzzy
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "ບໍ່ມີ"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "ຕ້ອງມີ"
+
+#, fuzzy
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "ບໍ່ມີ"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "ຕ້ອງມີ"
+
+#, fuzzy
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "ບໍ່ມີ"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "ຕ້ອງມີ"
+
+#, fuzzy
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "ບໍ່ມີ"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "ຕ້ອງມີ"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "ບໍ່ມີ"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "ຕ້ອງມີ"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "ບໍ່ມີ"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "ຕ້ອງມີ"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/lt.po b/modules/stock_lot_sled/locale/lt.po
new file mode 100644
index 0000000000..269646e458
--- /dev/null
+++ b/modules/stock_lot_sled/locale/lt.po
@@ -0,0 +1,227 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Stock Force Expiration"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/nl.po b/modules/stock_lot_sled/locale/nl.po
new file mode 100644
index 0000000000..41087b02a1
--- /dev/null
+++ b/modules/stock_lot_sled/locale/nl.po
@@ -0,0 +1,233 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr "Houdbaarheid status"
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr "Houdbaarheidsdatum"
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Houdbaarheidstermijn status"
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Houdbaarheidstermijn"
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr "Houdbaarheid status"
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr "Houdbaarheids datum"
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Houdbaarheidstermijn status"
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Houdbaarheidstermijn"
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Houdbaarheidsvertraging"
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Houdbaarheidsvertraging"
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Uiterste houdbaarheidsdatum"
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Houdbaarheid status"
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Uiterste houdbaarheidstermijn"
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Houdbaarheidstermijn status"
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Uiterste houdbaarheidsdatum"
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Houdbaarheid status"
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Uiterste houdbaarheidstermijn"
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Houdbaarheidstermijn status"
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr "In aantal dagen."
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr "In aantal dagen."
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr "In aantal dagen."
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr "In aantal dagen."
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "De vertraging voor de verwijdering uit de prognose."
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "De vertraging voor de verwijdering uit de prognose."
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+"U kunt de houdbaarheidsdatums van batch \"%(lot)s niet wijzigen omdat het "
+"wordt gebruikt bij voorraadboeking \"%(move)s\" in een afgesloten periode."
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+"U kunt de voorraadboeking \"%(move)s\" niet verwerken omdat de batch "
+"\"%(lot)s verlopen is."
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+"U kunt geen periodes afsluiten vóór het verlopen van batch \"%(lot)s\" "
+"(%(date)s)."
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Voorraad dwingt houdbaarheidsdatum af"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr "Voorraadconfiguratie Batch Houdbaarheidstermijn"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "Geen"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr "Optioneel"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "Vereist"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "Geen"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr "Optioneel"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "Vereist"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "Geen"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr "Optioneel"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "Vereist"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "Geen"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr "Optioneel"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "Vereist"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "Geen"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr "Optioneel"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "Vereist"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Geen"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Optioneel"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Vereist"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "Geen"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr "Optioneel"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "Vereist"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Geen"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Optioneel"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Vereist"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr "Houdbaarheidstermijn"
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr "Batch"
diff --git a/modules/stock_lot_sled/locale/pl.po b/modules/stock_lot_sled/locale/pl.po
new file mode 100644
index 0000000000..29148f17d6
--- /dev/null
+++ b/modules/stock_lot_sled/locale/pl.po
@@ -0,0 +1,242 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr "Termin ważności"
+
+#, fuzzy
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr "Termin ważności"
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr "Termin ważności"
+
+#, fuzzy
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr "Termin ważności"
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Termin ważności"
+
+#, fuzzy
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Termin ważności"
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Termin ważności"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Termin ważności"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Termin ważności"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Termin ważności"
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Stock Force Expiration"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "Brak"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr "Opcjonalny"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "Wymagany"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "Brak"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr "Opcjonalny"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "Wymagany"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "Brak"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr "Opcjonalny"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "Wymagany"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "Brak"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr "Opcjonalny"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "Wymagany"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "Brak"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr "Opcjonalny"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "Wymagany"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Brak"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Opcjonalny"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Wymagany"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "Brak"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr "Opcjonalny"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "Wymagany"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Brak"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Opcjonalny"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Wymagany"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/pt.po b/modules/stock_lot_sled/locale/pt.po
new file mode 100644
index 0000000000..2d35193c82
--- /dev/null
+++ b/modules/stock_lot_sled/locale/pt.po
@@ -0,0 +1,245 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr "Data de Expiração"
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr "Hora de Expiração"
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Estado do Tempo de Vida Útil"
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Tempo de Vida Útil"
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr "Data de Expiração"
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr "Hora de Expiração"
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Estado do Tempo de Vida Útil"
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Tempo de Vida Útil"
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Atraso da Vida Útil"
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Atraso da Vida Útil"
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Data de Expiração"
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Estado de Expiração"
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Data de Expiração da Vida Útil"
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Estado de Expiração da Vida Útil"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Data de Expiração"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Data de Expiração"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Data de Expiração da Vida Útil"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Estado de Expiração da Vida Útil"
+
+#, fuzzy
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr "Em número de dias"
+
+#, fuzzy
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr "Em número de dias"
+
+#, fuzzy
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr "Em número de dias"
+
+#, fuzzy
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr "Em número de dias"
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "O atraso antes da remoção da previsão."
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "O atraso antes da remoção da previsão."
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+"Você não pode modificar as datas de expiralção do lote \"%(lot)s\" proque "
+"ele foi usado na movimentação \"%(move)s\" em um período fechado."
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Stock Force Expiration"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr "Configuração de Estoque Vida Útil do Lote"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "Nenhum"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "Requerido"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "Nenhum"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "Requerido"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "Nenhum"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "Requerido"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "Nenhum"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "Requerido"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "Nenhum"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "Requerido"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Nenhum"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Requerido"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "Nenhum"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "Requerido"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Nenhum"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Opcional"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Requerido"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr "Vida Útil"
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/ro.po b/modules/stock_lot_sled/locale/ro.po
new file mode 100644
index 0000000000..8106d6b0c4
--- /dev/null
+++ b/modules/stock_lot_sled/locale/ro.po
@@ -0,0 +1,227 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr ""
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/ru.po b/modules/stock_lot_sled/locale/ru.po
new file mode 100644
index 0000000000..f3f07e695d
--- /dev/null
+++ b/modules/stock_lot_sled/locale/ru.po
@@ -0,0 +1,257 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr "Дата окончания"
+
+#, fuzzy
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr "Дата окончания"
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr "Дата окончания"
+
+#, fuzzy
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr "Дата окончания"
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Дата окончания"
+
+#, fuzzy
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Дата окончания"
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Дата окончания"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Дата окончания"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Дата окончания"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Дата окончания"
+
+#, fuzzy
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr "После указанного количества дней"
+
+#, fuzzy
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr "После указанного количества дней"
+
+#, fuzzy
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr "После указанного количества дней"
+
+#, fuzzy
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr "После указанного количества дней"
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Stock Force Expiration"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "Отсутствует"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "Обязательный"
+
+#, fuzzy
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "Отсутствует"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "Обязательный"
+
+#, fuzzy
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "Отсутствует"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "Обязательный"
+
+#, fuzzy
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "Отсутствует"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "Обязательный"
+
+#, fuzzy
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "Отсутствует"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "Обязательный"
+
+#, fuzzy
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Отсутствует"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Обязательный"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "Отсутствует"
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "Обязательный"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Отсутствует"
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Обязательный"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/sl.po b/modules/stock_lot_sled/locale/sl.po
new file mode 100644
index 0000000000..e680753985
--- /dev/null
+++ b/modules/stock_lot_sled/locale/sl.po
@@ -0,0 +1,245 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr "Uporabnost"
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr "Rok"
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Trajanje"
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Rok"
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr "Uporabnost"
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr "Rok"
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr "Trajanje"
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr "Rok"
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Zakasnitev roka trajanja"
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr "Zakasnitev roka trajanja"
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Rok uporabe"
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Uporabnost"
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Rok trajanja"
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Trajanje"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "Rok uporabe"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "Uporabnost"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "Rok trajanja"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "Trajanje"
+
+#, fuzzy
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr "V dnevih"
+
+#, fuzzy
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr "V dnevih"
+
+#, fuzzy
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr "V dnevih"
+
+#, fuzzy
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr "V dnevih"
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "Zakasnitev pred odstranitvijo iz napovedi."
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr "Zakasnitev pred odstranitvijo iz napovedi."
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+"Rokov uporabe serije \"%(lot)s\" ni možno popravljati, ker so v knjižbi "
+"\"%(move)s\" zaključenega obdobja."
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Stock Force Expiration"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr "Konfiguracija roka trajanja serije"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr "Brez"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr "Neobvezno"
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr "Obvezno"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr "Brez"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr "Neobvezno"
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr "Obvezno"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr "Brez"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr "Neobvezno"
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr "Obvezno"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr "Brez"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr "Neobvezno"
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr "Obvezno"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr "Brez"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr "Neobvezno"
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr "Obvezno"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Brez"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Neobvezno"
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Obvezno"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr "Brez"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr "Neobvezno"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr "Obvezno"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr "Brez"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr "Neobvezno"
+
+#, fuzzy
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr "Obvezno"
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr "Rok trajanja"
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/tr.po b/modules/stock_lot_sled/locale/tr.po
new file mode 100644
index 0000000000..269646e458
--- /dev/null
+++ b/modules/stock_lot_sled/locale/tr.po
@@ -0,0 +1,227 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Stock Force Expiration"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/uk.po b/modules/stock_lot_sled/locale/uk.po
new file mode 100644
index 0000000000..8106d6b0c4
--- /dev/null
+++ b/modules/stock_lot_sled/locale/uk.po
@@ -0,0 +1,227 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr ""
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/locale/zh_CN.po b/modules/stock_lot_sled/locale/zh_CN.po
new file mode 100644
index 0000000000..180626016b
--- /dev/null
+++ b/modules/stock_lot_sled/locale/zh_CN.po
@@ -0,0 +1,237 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:product.product,expiration_state:"
+msgid "Expiration State"
+msgstr "失效日期"
+
+#, fuzzy
+msgctxt "field:product.product,expiration_time:"
+msgid "Expiration Time"
+msgstr "失效日期"
+
+msgctxt "field:product.product,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.product,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:product.template,expiration_state:"
+msgid "Expiration State"
+msgstr "失效日期"
+
+#, fuzzy
+msgctxt "field:product.template,expiration_time:"
+msgid "Expiration Time"
+msgstr "失效日期"
+
+msgctxt "field:product.template,shelf_life_state:"
+msgid "Shelf Life Time State"
+msgstr ""
+
+msgctxt "field:product.template,shelf_life_time:"
+msgid "Shelf Life Time"
+msgstr ""
+
+msgctxt "field:stock.configuration,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+msgctxt "field:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "Shelf Life Delay"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "失效日期"
+
+#, fuzzy
+msgctxt "field:stock.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "失效日期"
+
+msgctxt "field:stock.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr ""
+
+msgctxt "field:stock.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_date:"
+msgid "Expiration Date"
+msgstr "失效日期"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Expiration State"
+msgstr "失效日期"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_date:"
+msgid "Shelf Life Expiration Date"
+msgstr "失效日期"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Shelf Life Expiration State"
+msgstr "失效日期"
+
+msgctxt "help:product.product,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.product,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,expiration_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:product.template,shelf_life_time:"
+msgid "In number of days."
+msgstr ""
+
+msgctxt "help:stock.configuration,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "help:stock.location.lot.shelf_life,shelf_life_delay:"
+msgid "The delay before removal from the forecast."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_modify_expiration_date_period_close"
+msgid ""
+"You cannot modify expiration dates of lot \"%(lot)s because it is used on "
+"move \"%(move)s\" in a closed period."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_move_lot_expired"
+msgid "You cannot process move \"%(move)s\" because its lot \"%(lot)s\" has expired."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_period_close_sled"
+msgid ""
+"You cannot close periods before the expiration of lot \"%(lot)s\" "
+"(%(date)s)."
+msgstr ""
+
+msgctxt "model:res.group,name:group_stock_force_expiration"
+msgid "Stock Force Expiration"
+msgstr "Stock Force Expiration"
+
+msgctxt "model:stock.location.lot.shelf_life,name:"
+msgid "Stock Configuration Lot Shelf Life"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.product,shelf_life_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:product.template,shelf_life_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "None"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Optional"
+msgstr ""
+
+msgctxt "selection:stock.move.add.lots.start.lot,shelf_life_expiration_state:"
+msgid "Required"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Shelf Life"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Lot"
+msgstr ""
diff --git a/modules/stock_lot_sled/message.xml b/modules/stock_lot_sled/message.xml
new file mode 100644
index 0000000000..492d37852e
--- /dev/null
+++ b/modules/stock_lot_sled/message.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ You cannot modify expiration dates of lot "%(lot)s because it is used on move "%(move)s" in a closed period.
+
+
+ You cannot process move "%(move)s" because its lot "%(lot)s" has expired.
+
+
+ You cannot close periods before the expiration of lot "%(lot)s" (%(date)s).
+
+
+
diff --git a/modules/stock_lot_sled/product.py b/modules/stock_lot_sled/product.py
new file mode 100644
index 0000000000..3f168291d1
--- /dev/null
+++ b/modules/stock_lot_sled/product.py
@@ -0,0 +1,38 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.model import fields
+from trytond.pool import PoolMeta
+from trytond.pyson import Eval
+
+from .stock import DATE_STATE
+
+
+class Template(metaclass=PoolMeta):
+ __name__ = 'product.template'
+
+ shelf_life_state = fields.Selection(
+ DATE_STATE, 'Shelf Life Time State', sort=False)
+ shelf_life_time = fields.Integer('Shelf Life Time',
+ states={
+ 'invisible': Eval('shelf_life_state', 'none') == 'none',
+ },
+ help='In number of days.')
+ expiration_state = fields.Selection(
+ DATE_STATE, 'Expiration State', sort=False)
+ expiration_time = fields.Integer('Expiration Time',
+ states={
+ 'invisible': Eval('expiration_state', 'none') == 'none',
+ },
+ help='In number of days.')
+
+ @staticmethod
+ def default_shelf_life_state():
+ return 'none'
+
+ @staticmethod
+ def default_expiration_state():
+ return 'none'
+
+
+class Product(metaclass=PoolMeta):
+ __name__ = 'product.product'
diff --git a/modules/stock_lot_sled/product.xml b/modules/stock_lot_sled/product.xml
new file mode 100644
index 0000000000..70184cd889
--- /dev/null
+++ b/modules/stock_lot_sled/product.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ product.template
+
+ template_form
+
+
+
diff --git a/modules/stock_lot_sled/setup.py b/modules/stock_lot_sled/setup.py
new file mode 100755
index 0000000000..c0a4e54063
--- /dev/null
+++ b/modules/stock_lot_sled/setup.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_lot_sled'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = ['python-sql >= 0.5']
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+tests_require = []
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module for shelf life expiration date of product lots',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_lot_sled',
+ },
+ keywords='tryton stock lot',
+ package_dir={'trytond.modules.stock_lot_sled': '.'},
+ packages=(
+ ['trytond.modules.stock_lot_sled']
+ + ['trytond.modules.stock_lot_sled.%s' % p for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_lot_sled': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'Intended Audience :: Manufacturing',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_lot_sled = trytond.modules.stock_lot_sled
+ """,
+ )
diff --git a/modules/stock_lot_sled/stock.py b/modules/stock_lot_sled/stock.py
new file mode 100644
index 0000000000..111b160821
--- /dev/null
+++ b/modules/stock_lot_sled/stock.py
@@ -0,0 +1,398 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import datetime
+
+from sql import As, Join, Null, Select, Table, Union
+from sql.conditionals import Greatest
+
+from trytond.i18n import gettext
+from trytond.model import ModelSQL, ModelView, ValueMixin, Workflow, fields
+from trytond.model.exceptions import AccessError
+from trytond.modules.stock.exceptions import PeriodCloseError
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Eval
+from trytond.tools import grouped_slice
+from trytond.transaction import Transaction
+
+from .exceptions import LotExpiredError, LotExpiredWarning
+
+DATE_STATE = [
+ ('none', 'None'),
+ ('optional', 'Optional'),
+ ('required', 'Required'),
+ ]
+shelf_life_delay = fields.TimeDelta(
+ "Shelf Life Delay",
+ help="The delay before removal from the forecast.")
+
+
+class Configuration(metaclass=PoolMeta):
+ __name__ = 'stock.configuration'
+
+ shelf_life_delay = fields.MultiValue(shelf_life_delay)
+
+ @classmethod
+ def multivalue_model(cls, field):
+ pool = Pool()
+ if field == 'shelf_life_delay':
+ return pool.get('stock.location.lot.shelf_life')
+ return super(Configuration, cls).multivalue_model(field)
+
+
+class ConfigurationLotShelfLife(ModelSQL, ValueMixin):
+ "Stock Configuration Lot Shelf Life"
+ __name__ = 'stock.location.lot.shelf_life'
+ shelf_life_delay = shelf_life_delay
+
+
+class LotSledMixin:
+ __slots__ = ()
+ shelf_life_expiration_date = fields.Date('Shelf Life Expiration Date',
+ states={
+ 'required': (
+ Eval('shelf_life_expiration_state', 'none') == 'required'),
+ 'invisible': Eval('shelf_life_expiration_state', 'none') == 'none',
+ })
+ shelf_life_expiration_state = fields.Function(
+ fields.Selection(DATE_STATE, 'Shelf Life Expiration State'),
+ 'on_change_with_shelf_life_expiration_state')
+ expiration_date = fields.Date('Expiration Date',
+ states={
+ 'required': Eval('expiration_state', 'none') == 'required',
+ 'invisible': Eval('expiration_state', 'none') == 'none',
+ })
+ expiration_state = fields.Function(
+ fields.Selection(DATE_STATE, 'Expiration State'),
+ 'on_change_with_expiration_state')
+
+ @fields.depends('product')
+ def on_change_with_shelf_life_expiration_state(self, name=None):
+ if self.product:
+ return self.product.shelf_life_state
+ return 'none'
+
+ @fields.depends('product')
+ def on_change_with_expiration_state(self, name=None):
+ if self.product:
+ return self.product.expiration_state
+ return 'none'
+
+ @fields.depends('product')
+ def on_change_product(self):
+ pool = Pool()
+ Date = pool.get('ir.date')
+ try:
+ super().on_change_product()
+ except AttributeError:
+ pass
+ if self.product:
+ today = Date.today()
+ if (self.product.shelf_life_state != 'none'
+ and self.product.shelf_life_time):
+ self.shelf_life_expiration_date = (today
+ + datetime.timedelta(days=self.product.shelf_life_time))
+ if (self.product.expiration_state != 'none'
+ and self.product.expiration_time):
+ self.expiration_date = (today
+ + datetime.timedelta(days=self.product.expiration_time))
+
+
+class Lot(LotSledMixin, metaclass=PoolMeta):
+ __name__ = 'stock.lot'
+
+ @classmethod
+ def write(cls, *args):
+ super(Lot, cls).write(*args)
+
+ actions = iter(args)
+ for lots, values in zip(actions, actions):
+ if any(f in ['shelf_life_expiration_date', 'expiration_date']
+ for f in values):
+ cls.check_sled_period_closed(lots)
+
+ @classmethod
+ def check_sled_period_closed(cls, lots):
+ Period = Pool().get('stock.period')
+ Move = Pool().get('stock.move')
+ periods = Period.search([
+ ('state', '=', 'closed'),
+ ], order=[('date', 'DESC')], limit=1)
+ if not periods:
+ return
+ period, = periods
+ for lots in grouped_slice(lots):
+ lot_ids = [l.id for l in lots]
+ moves = Move.search([
+ ('lot', 'in', lot_ids),
+ ['OR', [
+ ('effective_date', '=', None),
+ ('planned_date', '<=', period.date),
+ ],
+ ('effective_date', '<=', period.date),
+ ]], limit=1)
+ if moves:
+ move, = moves
+ raise AccessError(
+ gettext('stock_lot_sled'
+ '.msg_lot_modify_expiration_date_period_close',
+ lot=move.lot.rec_name,
+ move=move.rec_name))
+
+
+class MoveAddLotsStartLot(LotSledMixin, metaclass=PoolMeta):
+ __name__ = 'stock.move.add.lots.start.lot'
+
+ @fields.depends('shelf_life_expiration_date', 'expiration_date')
+ def _set_lot_values(self, lot):
+ super()._set_lot_values(lot)
+ self.shelf_life_expiration_date = lot.shelf_life_expiration_date
+ self.expiration_date = lot.expiration_date
+
+ def _get_lot_values(self, move):
+ values = super()._get_lot_values(move)
+ values['shelf_life_expiration_date'] = self.shelf_life_expiration_date
+ values['expiration_date'] = self.expiration_date
+ return values
+
+
+class Move(metaclass=PoolMeta):
+ __name__ = 'stock.move'
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('done')
+ def do(cls, moves):
+ super(Move, cls).do(moves)
+ cls.check_expiration_dates(moves)
+
+ @classmethod
+ def check_expiration_dates_types(cls):
+ "Location types to check for expiration dates"
+ return ['supplier', 'customer', 'production']
+
+ @classmethod
+ def check_expiration_dates_locations(cls):
+ pool = Pool()
+ Location = pool.get('stock.location')
+ # Prevent pack expired products
+ warehouses = Location.search([
+ ('type', '=', 'warehouse'),
+ ])
+ return [w.output_location for w in warehouses]
+
+ @property
+ def to_check_expiration(self):
+ if (self.lot
+ and self.lot.shelf_life_expiration_date
+ and self.effective_date > self.lot.shelf_life_expiration_date):
+ return True
+ return False
+
+ @classmethod
+ def check_expiration_dates(cls, moves):
+ pool = Pool()
+ Group = pool.get('res.group')
+ User = pool.get('res.user')
+ ModelData = pool.get('ir.model.data')
+ Warning = pool.get('res.user.warning')
+
+ types = cls.check_expiration_dates_types()
+ locations = cls.check_expiration_dates_locations()
+
+ def in_group():
+ group = Group(ModelData.get_id('stock_lot_sled',
+ 'group_stock_force_expiration'))
+ transition = Transaction()
+ user_id = transition.user
+ if user_id == 0:
+ user_id = transition.context.get('user', user_id)
+ if user_id == 0:
+ return True
+ user = User(user_id)
+ return group in user.groups
+
+ for move in moves:
+ if not move.to_check_expiration:
+ continue
+ if (move.from_location.type in types
+ or move.to_location.type in types
+ or move.from_location in locations
+ or move.to_location in locations):
+ values = {
+ 'move': move.rec_name,
+ 'lot': move.lot.rec_name if move.lot else '',
+ }
+ if not in_group():
+ raise LotExpiredError(
+ gettext('stock_lot_sled.msg_move_lot_expired',
+ **values))
+ else:
+ warning_name = '%s.check_expiration_dates' % move
+ if Warning.check(warning_name):
+ raise LotExpiredWarning(warning_name,
+ gettext('stock_lot_sled.msg_move_lot_expired',
+ **values))
+
+ @classmethod
+ def compute_quantities_query(cls, location_ids, with_childs=False,
+ grouping=('product',), grouping_filter=None):
+ pool = Pool()
+ Date = pool.get('ir.date')
+ Lot = pool.get('stock.lot')
+ Config = pool.get('stock.configuration')
+
+ query = super(Move, cls).compute_quantities_query(
+ location_ids, with_childs=with_childs, grouping=grouping,
+ grouping_filter=grouping_filter)
+
+ context = Transaction().context
+ today = Date.today()
+
+ stock_date_end = context.get('stock_date_end') or datetime.date.max
+ if (query and not context.get('skip_lot_sled')
+ and ((stock_date_end == today and context.get('forecast'))
+ or stock_date_end > today)):
+
+ config = Config(1)
+ shelf_life_delay = config.get_multivalue('shelf_life_delay')
+ if shelf_life_delay:
+ try:
+ expiration_date = stock_date_end + shelf_life_delay
+ except OverflowError:
+ if shelf_life_delay >= datetime.timedelta(0):
+ expiration_date = datetime.date.max
+ else:
+ expiration_date = datetime.date.min
+ else:
+ expiration_date = stock_date_end
+
+ def join(move, lot):
+ return move.join(lot, 'LEFT',
+ condition=move.lot == lot.id)
+
+ def find_table(join):
+ if not isinstance(join, Join):
+ return
+ for pos in ['left', 'right']:
+ item = getattr(join, pos)
+ if isinstance(item, Table):
+ if item._name == cls._table:
+ return join, pos, item
+ else:
+ found = find_table(item)
+ if found:
+ return found
+
+ def find_queries(query):
+ if isinstance(query, Union):
+ for sub_query in query.queries:
+ for q in find_queries(sub_query):
+ yield q
+ elif isinstance(query, Select):
+ yield query
+ for table in query.from_:
+ for q in find_queries(table):
+ yield q
+ elif isinstance(query, Join):
+ for pos in ['left', 'right']:
+ item = getattr(query, pos)
+ for q in find_queries(item):
+ yield q
+
+ def add_join(from_, lot):
+ # Find move table
+ for i, table in enumerate(from_):
+ if isinstance(table, Table) and table._name == cls._table:
+ sub_query.from_[i] = join(table, lot)
+ break
+ found = find_table(table)
+ if found:
+ join_, pos, table = found
+ setattr(join_, pos, join(table, lot))
+ break
+ else:
+ # Not query on move table
+ return False
+ return True
+
+ union, = query.from_
+ for sub_query in find_queries(union):
+ lot = Lot.__table__()
+ if add_join(sub_query.from_, lot):
+ clause = (
+ (lot.shelf_life_expiration_date == Null)
+ | (lot.shelf_life_expiration_date >= expiration_date))
+ if sub_query.where:
+ sub_query.where &= clause
+ else:
+ sub_query.where = clause
+
+ stock_date_start = context.get('stock_date_start')
+ if stock_date_start:
+ with Transaction().set_context(
+ stock_date_start=None,
+ skip_lot_sled=True):
+ query_expired = cls.compute_quantities_query(
+ location_ids, with_childs=with_childs,
+ grouping=grouping, grouping_filter=grouping_filter)
+ union_expired, = query_expired.from_
+ for sub_query in find_queries(union_expired):
+ lot = Lot.__table__()
+ if add_join(sub_query.from_, lot):
+ # only lot expiring during the period
+ clause = (
+ (lot.shelf_life_expiration_date
+ >= stock_date_start)
+ & (lot.shelf_life_expiration_date
+ < stock_date_end))
+ if sub_query.where:
+ sub_query.where &= clause
+ else:
+ sub_query.where = clause
+ # Inverse quantity
+ for column in sub_query._columns:
+ if (isinstance(column, As)
+ and column.output_name == 'quantity'):
+ column.expression = -column.expression
+ union.queries += union_expired.queries
+ return query
+
+
+class Period(metaclass=PoolMeta):
+ __name__ = 'stock.period'
+
+ @classmethod
+ @ModelView.button
+ def close(cls, periods):
+ pool = Pool()
+ Move = pool.get('stock.move')
+ Lot = pool.get('stock.lot')
+ Date = pool.get('ir.date')
+ Lang = pool.get('ir.lang')
+ cursor = Transaction().connection.cursor()
+ move = Move.__table__()
+ lot = Lot.__table__()
+
+ super(Period, cls).close(periods)
+
+ # Don't allow to close a period if all products at this date
+ # are not yet expired
+ recent_date = max(period.date for period in periods)
+ today = Date.today()
+
+ query = move.join(lot, 'INNER',
+ condition=move.lot == lot.id).select(lot.id,
+ where=(Greatest(move.effective_date, move.planned_date)
+ <= recent_date)
+ & (lot.shelf_life_expiration_date >= today)
+ )
+ cursor.execute(*query)
+ lot_id = cursor.fetchone()
+ if lot_id:
+ lot_id, = lot_id
+ lot = Lot(lot_id)
+ lang = Lang.get()
+ raise PeriodCloseError(
+ gettext('stock_lot_sled.msg_period_close_sled',
+ lot=lot.rec_name,
+ date=lang.strftime(lot.shelf_life_expiration_date)))
diff --git a/modules/stock_lot_sled/stock.xml b/modules/stock_lot_sled/stock.xml
new file mode 100644
index 0000000000..7f563dea7e
--- /dev/null
+++ b/modules/stock_lot_sled/stock.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+ Stock Force Expiration
+
+
+
+
+
+
+
+ stock.configuration
+
+ configuration_form
+
+
+
+ stock.lot
+
+ lot_form
+
+
+ stock.lot
+
+ lot_tree
+
+
+
+ stock.move.add.lots.start.lot
+
+ lot_tree
+
+
+
diff --git a/modules/stock_lot_sled/tests/__init__.py b/modules/stock_lot_sled/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_lot_sled/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_lot_sled/tests/test_module.py b/modules/stock_lot_sled/tests/test_module.py
new file mode 100644
index 0000000000..9464ff3c3c
--- /dev/null
+++ b/modules/stock_lot_sled/tests/test_module.py
@@ -0,0 +1,161 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import datetime
+
+from trytond.modules.company.tests import (
+ CompanyTestMixin, create_company, set_company)
+from trytond.pool import Pool
+from trytond.tests.test_tryton import ModuleTestCase, with_transaction
+from trytond.transaction import Transaction
+
+
+class StockLotSLEDTestCase(CompanyTestMixin, ModuleTestCase):
+ 'Test Stock Lot SLED module'
+ module = 'stock_lot_sled'
+ longMessage = True
+
+ @with_transaction()
+ def test_sled(self):
+ 'Test SLED'
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ Template = pool.get('product.template')
+ Product = pool.get('product.product')
+ Location = pool.get('stock.location')
+ Date = pool.get('ir.date')
+ Move = pool.get('stock.move')
+ Lot = pool.get('stock.lot')
+ Period = pool.get('stock.period')
+ Config = pool.get('stock.configuration')
+
+ u, = Uom.search([('name', '=', 'Unit')])
+ template = Template(
+ name='Test SLED',
+ type='goods',
+ default_uom=u,
+ shelf_life_state='optional',
+ )
+ template.save()
+ product = Product(template=template)
+ product.save()
+
+ supplier, = Location.search([('code', '=', 'SUP')])
+ storage, = Location.search([('code', '=', 'CUS')])
+
+ company = create_company()
+ with set_company(company):
+ today = Date.today()
+
+ lot = Lot(
+ number='Test',
+ product=product,
+ shelf_life_expiration_date=today + datetime.timedelta(days=5),
+ )
+ lot.save()
+
+ move = Move(
+ product=product,
+ uom=u,
+ quantity=5,
+ from_location=supplier,
+ to_location=storage,
+ planned_date=today,
+ company=company,
+ unit_price=0,
+ currency=company.currency,
+ lot=lot,
+ )
+ move.save()
+
+ period = Period(date=today + datetime.timedelta(days=-10),
+ company=company)
+ period.save()
+ Period.close([period])
+
+ config = Config(1)
+
+ empty = {}
+ computed = {(storage.id, product.id): 5}
+ delta = {(storage.id, product.id): -5}
+ for context, result in [
+ ({'stock_date_end': datetime.date.min}, empty),
+ ({'stock_date_end': today + datetime.timedelta(days=-1)},
+ empty),
+ ({'stock_date_end': today}, empty),
+ ({'stock_date_end': today, 'forecast': True}, computed),
+ ({'stock_date_end': today + datetime.timedelta(days=3)},
+ computed),
+ ({'stock_date_end': today + datetime.timedelta(days=5)},
+ computed),
+ ({'stock_date_end': today + datetime.timedelta(days=6)},
+ empty),
+ ({}, empty),
+ ({'stock_date_start': today, 'stock_date_end': today},
+ empty),
+ ({'stock_date_start': today + datetime.timedelta(days=1),
+ 'stock_date_end': today + datetime.timedelta(days=7)},
+ delta),
+ ({'stock_date_start': today + datetime.timedelta(days=1),
+ 'stock_date_end': today + datetime.timedelta(days=2)},
+ empty),
+ ({'stock_date_start': today + datetime.timedelta(days=1),
+ 'stock_date_end': today + datetime.timedelta(days=5)},
+ empty),
+ ({'stock_date_start': today + datetime.timedelta(days=5),
+ 'stock_date_end': today + datetime.timedelta(days=6)},
+ delta),
+ ({'stock_date_start': today + datetime.timedelta(days=5),
+ 'stock_date_end': today + datetime.timedelta(days=7)},
+ delta),
+ ({'stock_date_start': today + datetime.timedelta(days=6),
+ 'stock_date_end': today + datetime.timedelta(days=7)},
+ empty),
+ ({'stock_date_end': datetime.date.max}, empty),
+ ]:
+ with Transaction().set_context(context=context,
+ locations=[storage.id]):
+ quantity = Product.products_by_location(
+ [storage.id], grouping_filter=([product.id],))
+ self.assertEqual(quantity, result,
+ msg='context: %s' % repr(context))
+
+ quantity = Product.products_by_location(
+ [storage.id], grouping_filter=([product.id],),
+ with_childs=True)
+ self.assertEqual(quantity, result,
+ msg='context: %s, with childs' % repr(context))
+
+ quantity = Product.products_by_location(
+ [storage.id],
+ grouping=('product.template',),
+ grouping_filter=([product.template.id],),)
+ self.assertEqual(quantity, result,
+ msg='template, context: %s' % repr(context))
+
+ quantity = Product.products_by_location(
+ [storage.id],
+ grouping=('product.template',),
+ grouping_filter=([product.template.id],),
+ with_childs=True)
+ self.assertEqual(quantity, result,
+ msg='template, context: %s, with_childs' %
+ repr(context))
+
+ for context, delay, result in [
+ ({'stock_date_end': datetime.date.min},
+ datetime.timedelta(days=-1), empty),
+ ({'stock_date_end': datetime.date.max},
+ datetime.timedelta(days=1), empty),
+ ]:
+ config.shelf_life_delay = delay
+ config.save()
+ with Transaction().set_context(context=context,
+ locations=[storage.id]):
+ quantity = Product.products_by_location(
+ [storage.id], grouping_filter=([product.id],))
+ self.assertEqual(quantity, result,
+ msg='context: %s; shelf_life_delay: %s' %
+ (repr(context), delay))
+
+
+del ModuleTestCase
diff --git a/modules/stock_lot_sled/tox.ini b/modules/stock_lot_sled/tox.ini
new file mode 100644
index 0000000000..40913d4cdb
--- /dev/null
+++ b/modules/stock_lot_sled/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_lot_sled/* -m unittest discover -s tests
+ coverage report --include=./**/stock_lot_sled/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_lot_sled/tryton.cfg b/modules/stock_lot_sled/tryton.cfg
new file mode 100644
index 0000000000..33acb9d245
--- /dev/null
+++ b/modules/stock_lot_sled/tryton.cfg
@@ -0,0 +1,11 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ product
+ stock
+ stock_lot
+xml:
+ stock.xml
+ product.xml
+ message.xml
diff --git a/modules/stock_lot_sled/view/configuration_form.xml b/modules/stock_lot_sled/view/configuration_form.xml
new file mode 100644
index 0000000000..27e5c931a8
--- /dev/null
+++ b/modules/stock_lot_sled/view/configuration_form.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot_sled/view/lot_form.xml b/modules/stock_lot_sled/view/lot_form.xml
new file mode 100644
index 0000000000..11acbc1b05
--- /dev/null
+++ b/modules/stock_lot_sled/view/lot_form.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot_sled/view/lot_tree.xml b/modules/stock_lot_sled/view/lot_tree.xml
new file mode 100644
index 0000000000..911d8c805b
--- /dev/null
+++ b/modules/stock_lot_sled/view/lot_tree.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot_sled/view/template_form.xml b/modules/stock_lot_sled/view/template_form.xml
new file mode 100644
index 0000000000..cf4ffa3955
--- /dev/null
+++ b/modules/stock_lot_sled/view/template_form.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot_unit/.drone.yml b/modules/stock_lot_unit/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_lot_unit/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_lot_unit/.flake8 b/modules/stock_lot_unit/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_lot_unit/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_lot_unit/.isort.cfg b/modules/stock_lot_unit/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_lot_unit/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_lot_unit/CHANGELOG b/modules/stock_lot_unit/CHANGELOG
new file mode 100644
index 0000000000..edf72b86be
--- /dev/null
+++ b/modules/stock_lot_unit/CHANGELOG
@@ -0,0 +1,30 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Initial release
diff --git a/modules/stock_lot_unit/COPYRIGHT b/modules/stock_lot_unit/COPYRIGHT
new file mode 100644
index 0000000000..b075873b71
--- /dev/null
+++ b/modules/stock_lot_unit/COPYRIGHT
@@ -0,0 +1,16 @@
+Copyright (C) 2018-2022 Cédric Krier
+Copyright (C) 2017-2022 Nicolas Évrard
+Copyright (C) 2017-2022 B2CK
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_lot_unit/LICENSE b/modules/stock_lot_unit/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_lot_unit/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_lot_unit/MANIFEST.in b/modules/stock_lot_unit/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_lot_unit/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_lot_unit/README.rst b/modules/stock_lot_unit/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_lot_unit/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_lot_unit/__init__.py b/modules/stock_lot_unit/__init__.py
new file mode 100644
index 0000000000..124ac6867c
--- /dev/null
+++ b/modules/stock_lot_unit/__init__.py
@@ -0,0 +1,31 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import product, stock
+from .stock import LotUnitMixin
+
+__all__ = ['LotUnitMixin', 'register']
+
+
+def register():
+ Pool.register(
+ product.Template,
+ product.Product,
+ stock.Lot,
+ stock.MoveAddLotsStartLot,
+ stock.Move,
+ stock.Inventory,
+ stock.ShipmentIn,
+ stock.ShipmentInReturn,
+ stock.ShipmentOut,
+ stock.ShipmentOutReturn,
+ module='stock_lot_unit', type_='model')
+ Pool.register(
+ stock.Production,
+ module='stock_lot_unit', type_='model',
+ depends=['production'])
+ Pool.register(
+ stock.InventoryCount,
+ module='stock_lot_unit', type_='wizard')
diff --git a/modules/stock_lot_unit/doc/index.rst b/modules/stock_lot_unit/doc/index.rst
new file mode 100644
index 0000000000..f8858c1371
--- /dev/null
+++ b/modules/stock_lot_unit/doc/index.rst
@@ -0,0 +1,14 @@
+Stock Lot Unit Module
+#####################
+
+The `stock_lot_unit` module allows to define a unit and quantity on stock lot.
+
+Lots with unit have the following properties:
+
+ - no shipment may contain a summed quantity for a lot greater than the
+ quantity of the lot.
+ - no move related to a lot with a unit may concern a quantity greater than
+ the quantity of the lot.
+
+The *Lot Unit* field is added to the product. This defines the unit to set on
+new lot.
diff --git a/modules/stock_lot_unit/exceptions.py b/modules/stock_lot_unit/exceptions.py
new file mode 100644
index 0000000000..1f4b167d61
--- /dev/null
+++ b/modules/stock_lot_unit/exceptions.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.model.exceptions import ValidationError
+
+
+class LotUnitQuantityError(ValidationError):
+ pass
diff --git a/modules/stock_lot_unit/locale/bg.po b/modules/stock_lot_unit/locale/bg.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/bg.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/locale/ca.po b/modules/stock_lot_unit/locale/ca.po
new file mode 100644
index 0000000000..4df5e1d58d
--- /dev/null
+++ b/modules/stock_lot_unit/locale/ca.po
@@ -0,0 +1,76 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr "Unitat del lot"
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr "Unitat del lot"
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "Categoria UdM del producte"
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr "Unitat"
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "Quantitat unitària"
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "Categoria UdM del producte"
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr "Unitat"
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "Quantitat unitària"
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr "La unitat per defecte del lot."
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr "La unitat per defecte del lot."
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "La major unitat del lot."
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "La quantitat màxima del lot."
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "La major unitat del lot."
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "La quantitat màxima del lot."
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr "No podeu canviar la unitat d'un lot que té moviments d'existències."
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+"No podeu canviar la quantitat d'un lot que té moviments d'existències."
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
+"No podeu utililizar més de %(quantity)s%(unit)s del lot \"%(lot)s\" en "
+"\"%(name)s\"."
diff --git a/modules/stock_lot_unit/locale/cs.po b/modules/stock_lot_unit/locale/cs.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/cs.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/locale/de.po b/modules/stock_lot_unit/locale/de.po
new file mode 100644
index 0000000000..4274eff3ed
--- /dev/null
+++ b/modules/stock_lot_unit/locale/de.po
@@ -0,0 +1,79 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr "Chargeneinheit"
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr "Chargeneinheit"
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "Standardmaßeinheitenkategorie"
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr "Einheit"
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "Maßeinheit Menge"
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "Standardmaßeinheitenkategorie"
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr "Einheit"
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "Maßeinheit Menge"
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr "Standardmaßeinheit für Chargen."
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr "Standardmaßeinheit für Chargen."
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "Die größte Maßeinheit für die Charge."
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "Die maximale Menge für die Charge."
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "Die größte Maßeinheit für die Charge."
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "Die maximale Menge für die Charge."
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+"Die Einheit einer Charge, für die es Warenbewegungen gibt, kann nicht "
+"geändert werden."
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+"Die Menge einer Charge, für die es Warenbewegungen gibt, kann nicht gändert "
+"werden."
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
+"In \"%(name)s\" kann nicht mehr als %(quantity)s%(unit)s von Charge "
+"\"%(lot)s\" verwendet werden."
diff --git a/modules/stock_lot_unit/locale/es.po b/modules/stock_lot_unit/locale/es.po
new file mode 100644
index 0000000000..1e43d29539
--- /dev/null
+++ b/modules/stock_lot_unit/locale/es.po
@@ -0,0 +1,76 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr "Unidad del lote"
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr "Unidad del lote"
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "Cateogría de UdM de producto"
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr "Unidad"
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "Cantidad unitaria"
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "Cateogoría de UdM del producto"
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr "Unidad"
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "Cantidad unitaria"
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr "La unidad por defecto del lote."
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr "La unidad por defecto del lote."
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "La mayor unidad del lote."
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "La cantidad máxima del lote."
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "La mayor unidad del lote."
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "La cantidad máxima del lote."
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+"No puede cambiar la unidad de un lote que tiene movimientos de existencias."
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+"No puede cambiar la cantidad de un lote que tiene movimientos de "
+"existencias."
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr "No puede usar más de %(quantity)s%(unit)s del \"%(lot)s\" en \"%(name)s\"."
diff --git a/modules/stock_lot_unit/locale/es_419.po b/modules/stock_lot_unit/locale/es_419.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/es_419.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/locale/et.po b/modules/stock_lot_unit/locale/et.po
new file mode 100644
index 0000000000..7aed091b1e
--- /dev/null
+++ b/modules/stock_lot_unit/locale/et.po
@@ -0,0 +1,81 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr "Partii ühik"
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr "Partii ühik"
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "Vaikimisi toote mõõtühiku kategooria"
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr "Ühik"
+
+#, fuzzy
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "Kogus"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "Vaikimisi toote mõõtühiku kategooria"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr "Ühik"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "Kogus"
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr "Partii vaikeühik."
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr "Partii vaikeühik."
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "Partii suurim ühik."
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "Suurim partiikogus."
+
+#, fuzzy
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "Partii suurim ühik."
+
+#, fuzzy
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "Suurim partiikogus."
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr "Laoliikumistega seotud partii ühikut ei saa muuta."
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr "Laoliikumistega seotud partii kogust ei saa muuta."
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
+"\"%(name)s\" ei saa kasutada suuremat partii \"%(lot)s\" kogust "
+"%(quantity)s%(unit)s"
diff --git a/modules/stock_lot_unit/locale/fa.po b/modules/stock_lot_unit/locale/fa.po
new file mode 100644
index 0000000000..7b224eca4d
--- /dev/null
+++ b/modules/stock_lot_unit/locale/fa.po
@@ -0,0 +1,81 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr "واحد قطعه"
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr "واحد قطعه"
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "دسته بندی واحد اندازه گیری محصول پیشفرض"
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr "واحد"
+
+#, fuzzy
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "مقدار"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "دسته بندی واحد اندازه گیری محصول پیشفرض"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr "واحد"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "مقدار"
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr "واحد پیشفرض قطعه."
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr "واحد پیشفرض قطعه."
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "بزرگترین واحد برای قطعه"
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "حداکثر مقدار برای قطعه."
+
+#, fuzzy
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "بزرگترین واحد برای قطعه"
+
+#, fuzzy
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "حداکثر مقدار برای قطعه."
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr "شما نمی توانید یک واحد جنس را تغییر دهید که جابجایی اجناس داشته باشد."
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr "شما نمی توانید مقدار جنس را تغییر دهید که جابجایی اجناس داشته باشد."
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
+"شما نمی توانید بیش از:\"%(quantity)s%(unit)s\" از قطعه :\"%(lot)s\" "
+"در:\"%(name)s\" استفاده کنید."
diff --git a/modules/stock_lot_unit/locale/fi.po b/modules/stock_lot_unit/locale/fi.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/fi.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/locale/fr.po b/modules/stock_lot_unit/locale/fr.po
new file mode 100644
index 0000000000..ed4bde21de
--- /dev/null
+++ b/modules/stock_lot_unit/locale/fr.po
@@ -0,0 +1,78 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr "Unité de lot"
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr "Unité de lot"
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "Catégorie d'unité de mesure par défaut"
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr "Unité"
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "Quantité Unitaire"
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "Catégorie d'unité de mesure par défaut"
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr "Unité"
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "Quantité Unitaire"
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr "L'unité par défaut pour le lot."
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr "L'unité par défaut pour le lot."
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "La plus grande unité pour le lot."
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "La quantité maximal pour le lot."
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "La plus grande unité pour le lot."
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "La quantité maximal pour le lot."
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+"Vous ne pouvez pas changer l'unité d'un lot qui a des mouvements de stock."
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+"Vous ne pouvez pas changer la quantité d'un lot qui a des mouvements de "
+"stock."
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
+"Vous ne pouvez pas utiliser plus que %(quantity)s%(unit)s du lot « %(lot)s »"
+" sur « %(name)s »."
diff --git a/modules/stock_lot_unit/locale/hu.po b/modules/stock_lot_unit/locale/hu.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/hu.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/locale/id.po b/modules/stock_lot_unit/locale/id.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/id.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/locale/it.po b/modules/stock_lot_unit/locale/it.po
new file mode 100644
index 0000000000..821d0290a1
--- /dev/null
+++ b/modules/stock_lot_unit/locale/it.po
@@ -0,0 +1,81 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr "Lotto Unità"
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr "Lotto Unità"
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "Categoria UdM prodotto predefinita"
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr "Unità"
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "Quantità unitaria"
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "Categoria UdM prodotto predefinita"
+
+#, fuzzy
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr "Unità"
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "Quantità unitaria"
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr "L'unità predefinita per il lotto."
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr "L'unità predefinita per il lotto."
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "L'unità più grande per il lotto."
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "La quantità massima per il lotto."
+
+#, fuzzy
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "L'unità più grande per il lotto."
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "La quantità massima per il lotto."
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+"Non è possibile modificare l'unità di un lotto di stock che ha movimenti di "
+"stock."
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+"Non è possibile modificare la quantità di un lotto di stock che ha movimenti"
+" di stock."
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
+"Non è possibile utilizzare più di %(quantity)s%(unit)s del lotto \"%(lot)s\""
+" in \"%(name)s\"."
diff --git a/modules/stock_lot_unit/locale/lo.po b/modules/stock_lot_unit/locale/lo.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/lo.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/locale/lt.po b/modules/stock_lot_unit/locale/lt.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/lt.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/locale/nl.po b/modules/stock_lot_unit/locale/nl.po
new file mode 100644
index 0000000000..81eb65b0b0
--- /dev/null
+++ b/modules/stock_lot_unit/locale/nl.po
@@ -0,0 +1,78 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr "Batch eenheid"
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr "Batch eenheid"
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "Standaard Product Maateenheid Categorie"
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr "Eenheid"
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "Eenheid Hoeveelheid"
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr "Standaard Product Maateenheid Categorie"
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr "Eenheid"
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr "Eenheid Hoeveelheid"
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr "De standaard eenheid voor een batch."
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr "De standaard eenheid voor een batch."
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "De grootste eenheid voor een batch."
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "De maximale hoeveelheid voor een batch."
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr "De grootste eenheid voor het lot."
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr "De maximale hoeveelheid voor een batch."
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+"U kunt de eenheid van een batch die voorraadbewegingen heeft niet wijzigen."
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+"U kunt de hoeveelheid van een batch die voorraadbewegingen heeft niet "
+"wijzigen."
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
+"U kunt niet meer dan %(quantity)s%(unit)s van batch \"%(lot)s\" in \"% "
+"(name)s\" gebruiken."
diff --git a/modules/stock_lot_unit/locale/pl.po b/modules/stock_lot_unit/locale/pl.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/pl.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/locale/pt.po b/modules/stock_lot_unit/locale/pt.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/pt.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/locale/ro.po b/modules/stock_lot_unit/locale/ro.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/ro.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/locale/ru.po b/modules/stock_lot_unit/locale/ru.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/ru.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/locale/sl.po b/modules/stock_lot_unit/locale/sl.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/sl.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/locale/tr.po b/modules/stock_lot_unit/locale/tr.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/tr.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/locale/uk.po b/modules/stock_lot_unit/locale/uk.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/uk.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/locale/zh_CN.po b/modules/stock_lot_unit/locale/zh_CN.po
new file mode 100644
index 0000000000..fab9cb6cc5
--- /dev/null
+++ b/modules/stock_lot_unit/locale/zh_CN.po
@@ -0,0 +1,73 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:product.template,lot_unit:"
+msgid "Lot Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,product_default_uom_category:"
+msgid "Default Product UoM Category"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "Unit Quantity"
+msgstr ""
+
+msgctxt "help:product.product,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:product.template,lot_unit:"
+msgid "The default unit for lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit:"
+msgid "The biggest unit for the lot."
+msgstr ""
+
+msgctxt "help:stock.move.add.lots.start.lot,unit_quantity:"
+msgid "The maximal quantity for the lot."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit"
+msgid "You cannot change the unit of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_change_unit_quantity"
+msgid "You cannot change the quantity of a stock lot which has stock moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_lot_unit_quantity_greater"
+msgid ""
+"You cannot use more than %(quantity)s%(unit)s of lot \"%(lot)s\" in "
+"\"%(name)s\"."
+msgstr ""
diff --git a/modules/stock_lot_unit/message.xml b/modules/stock_lot_unit/message.xml
new file mode 100644
index 0000000000..f0412ef39d
--- /dev/null
+++ b/modules/stock_lot_unit/message.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ You cannot change the unit of a stock lot which has stock moves.
+
+
+ You cannot change the quantity of a stock lot which has stock moves.
+
+
+ You cannot use more than %(quantity)s%(unit)s of lot "%(lot)s" in "%(name)s".
+
+
+
diff --git a/modules/stock_lot_unit/product.py b/modules/stock_lot_unit/product.py
new file mode 100644
index 0000000000..f03700f435
--- /dev/null
+++ b/modules/stock_lot_unit/product.py
@@ -0,0 +1,23 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.model import fields
+from trytond.pool import PoolMeta
+from trytond.pyson import Eval
+
+
+class Template(metaclass=PoolMeta):
+ __name__ = 'product.template'
+
+ lot_unit = fields.Many2One('product.uom', "Lot Unit",
+ domain=[
+ ('category', '=', Eval('default_uom_category', -1)),
+ ],
+ states={
+ 'invisible': Eval('type') == 'service',
+ },
+ help="The default unit for lot.")
+
+
+class Product(metaclass=PoolMeta):
+ __name__ = 'product.product'
diff --git a/modules/stock_lot_unit/product.xml b/modules/stock_lot_unit/product.xml
new file mode 100644
index 0000000000..70184cd889
--- /dev/null
+++ b/modules/stock_lot_unit/product.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ product.template
+
+ template_form
+
+
+
diff --git a/modules/stock_lot_unit/setup.py b/modules/stock_lot_unit/setup.py
new file mode 100755
index 0000000000..b7f3e30593
--- /dev/null
+++ b/modules/stock_lot_unit/setup.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_lot_unit'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = []
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [get_require_version('proteus'),
+ get_require_version('trytond_production')]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module to define unit on stock lot',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_lot_unit',
+ },
+ keywords='tryton stock lot unit serial',
+ package_dir={'trytond.modules.stock_lot_unit': '.'},
+ packages=(
+ ['trytond.modules.stock_lot_unit']
+ + ['trytond.modules.stock_lot_unit.%s' % p for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_lot_unit': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Manufacturing',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_lot_unit = trytond.modules.stock_lot_unit
+ """,
+ )
diff --git a/modules/stock_lot_unit/stock.py b/modules/stock_lot_unit/stock.py
new file mode 100644
index 0000000000..939244a9ff
--- /dev/null
+++ b/modules/stock_lot_unit/stock.py
@@ -0,0 +1,213 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from collections import defaultdict
+
+from trytond.i18n import gettext
+from trytond.model import ModelView, Workflow, fields
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Bool, Eval
+
+from .exceptions import LotUnitQuantityError
+
+
+class LotUnitMixin:
+ __slots__ = ()
+ unit = fields.Many2One(
+ 'product.uom', "Unit",
+ domain=[
+ ('category', '=', Eval('product_default_uom_category', -1)),
+ ],
+ help="The biggest unit for the lot.")
+ unit_quantity = fields.Float(
+ "Unit Quantity", digits='unit',
+ states={
+ 'required': Bool(Eval('unit')),
+ 'invisible': ~Eval('unit'),
+ },
+ help="The maximal quantity for the lot.")
+
+ product_default_uom_category = fields.Function(
+ fields.Many2One(
+ 'product.uom.category', "Default Product UoM Category"),
+ 'on_change_with_product_default_uom_category')
+
+ @fields.depends('product', methods=['on_change_unit'])
+ def on_change_product(self):
+ try:
+ super().on_change_product()
+ except AttributeError:
+ pass
+ if self.product and self.product.lot_unit:
+ self.unit = self.product.lot_unit
+ self.on_change_unit()
+
+ @fields.depends('unit')
+ def on_change_unit(self):
+ if self.unit:
+ self.unit_quantity = self.unit.rounding
+
+ @fields.depends('product')
+ def on_change_with_product_default_uom_category(self, name=None):
+ if self.product:
+ category = self.product.default_uom_category
+ return category.id if category else None
+
+
+class Lot(LotUnitMixin, metaclass=PoolMeta):
+ __name__ = 'stock.lot'
+
+ @classmethod
+ def __setup__(cls):
+ super(Lot, cls).__setup__()
+ cls._modify_no_move += [
+ ('unit', 'done', 'stock_lot_unit.msg_change_unit'),
+ ('unit_quantity', 'done',
+ 'stock_lot_unit.msg_change_unit_quantity'),
+ ]
+
+
+class MoveAddLotsStartLot(LotUnitMixin, metaclass=PoolMeta):
+ __name__ = 'stock.move.add.lots.start.lot'
+
+ @fields.depends(
+ 'unit', 'unit_quantity', 'quantity', 'parent', '_parent_parent.unit')
+ def _set_lot_values(self, lot):
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ super()._set_lot_values(lot)
+ self.unit = lot.unit
+ self.unit_quantity = lot.unit_quantity
+ if self.parent.unit:
+ maximum_quantity = Uom.compute_qty(
+ lot.unit, lot.unit_quantity, self.parent.unit, round=False)
+ if self.quantity > maximum_quantity:
+ self.quantity = self.parent.unit.round(maximum_quantity)
+
+ def _get_lot_values(self, move):
+ values = super()._get_lot_values(move)
+ values['unit'] = self.unit
+ values['unit_quantity'] = self.unit_quantity
+ return values
+
+
+class Move(metaclass=PoolMeta):
+ __name__ = 'stock.move'
+
+ def check_lot(self):
+ pool = Pool()
+ UoM = pool.get('product.uom')
+ super(Move, self).check_lot()
+ if (self.state == 'done'
+ and self.lot
+ and self.lot.unit):
+ quantity = UoM.compute_qty(
+ self.uom, self.quantity,
+ self.lot.unit, round=False)
+ if quantity > self.lot.unit_quantity:
+ raise LotUnitQuantityError(
+ gettext('stock_lot_unit.msg_lot_unit_quantity_greater',
+ quantity=self.lot.unit_quantity,
+ unit=self.lot.unit.symbol,
+ lot=self.lot.rec_name,
+ name=self.rec_name))
+
+
+class Inventory(metaclass=PoolMeta):
+ __name__ = 'stock.inventory'
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('done')
+ def confirm(cls, inventories):
+ for inventory in inventories:
+ for line in inventory.lines:
+ if (line.quantity is not None
+ and line.lot
+ and line.lot.unit
+ and line.quantity > line.lot.unit_quantity):
+ raise LotUnitQuantityError(
+ gettext('stock_lot_unit.msg_lot_unit_quantity_greater',
+ quantity=line.lot.unit_quantity,
+ unit=line.lot.unit.symbol,
+ lot=line.lot.rec_name,
+ name=line.rec_name))
+ super(Inventory, cls).confirm(inventories)
+
+
+class InventoryCount(metaclass=PoolMeta):
+ __name__ = 'stock.inventory.count'
+
+ def default_quantity(self, fields):
+ pool = Pool()
+ InventoryLine = pool.get('stock.inventory.line')
+ UoM = pool.get('product.uom')
+ values = super(InventoryCount, self).default_quantity(fields)
+ line = InventoryLine(values['line'])
+ if line.lot and line.lot.unit:
+ values['quantity'] = UoM.compute_qty(
+ line.lot.unit, line.lot.unit_quantity,
+ line.uom)
+ return values
+
+
+class LotUnitMixin(object):
+ __slots__ = ()
+ _lot_unit_moves = None
+
+ @classmethod
+ def validate(cls, shipments):
+ pool = Pool()
+ UoM = pool.get('product.uom')
+
+ super(LotUnitMixin, cls).validate(shipments)
+
+ for shipment in shipments:
+ for move_attribute in cls._lot_unit_moves:
+ lot_quantities = defaultdict(int)
+ for move in getattr(shipment, move_attribute):
+ if move.state != 'done':
+ continue
+ if not move.lot or not move.lot.unit:
+ continue
+ lot_quantities[move.lot] += UoM.compute_qty(
+ move.uom, move.quantity,
+ move.lot.unit, round=False)
+ for lot, quantity in lot_quantities.items():
+ if quantity > lot.unit_quantity:
+ raise LotUnitQuantityError(
+ gettext('stock_lot_unit'
+ '.msg_lot_unit_quantity_greater',
+ quantity=lot.unit_quantity,
+ unit=lot.unit.symbol,
+ lot=lot.rec_name,
+ name=shipment.rec_name))
+
+
+class ShipmentIn(LotUnitMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in'
+ _lot_unit_moves = ['incoming_moves', 'inventory_moves']
+
+
+class ShipmentInReturn(LotUnitMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in.return'
+ _lot_unit_moves = ['moves']
+
+
+class ShipmentOut(LotUnitMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out'
+ _lot_unit_moves = ['outgoing_moves', 'inventory_moves']
+
+
+class ShipmentOutReturn(LotUnitMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out.return'
+ _lot_unit_moves = ['incoming_moves', 'inventory_moves']
+
+
+class ShipmentInternal(LotUnitMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.internal'
+ _lot_unit_moves = ['incoming_moves', 'outgoing_moves']
+
+
+class Production(LotUnitMixin, metaclass=PoolMeta):
+ __name__ = 'production'
+ _lot_unit_moves = ['inputs', 'outputs']
diff --git a/modules/stock_lot_unit/stock.xml b/modules/stock_lot_unit/stock.xml
new file mode 100644
index 0000000000..59e5a2d692
--- /dev/null
+++ b/modules/stock_lot_unit/stock.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+ stock.lot
+
+ lot_form
+
+
+
+ stock.lot
+
+ lot_list
+
+
+
+ stock.move.add.lots.start.lot
+
+ lot_list
+
+
+
diff --git a/modules/stock_lot_unit/tests/__init__.py b/modules/stock_lot_unit/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_lot_unit/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_lot_unit/tests/scenario_stock_lot_unit.rst b/modules/stock_lot_unit/tests/scenario_stock_lot_unit.rst
new file mode 100644
index 0000000000..dce1906b4c
--- /dev/null
+++ b/modules/stock_lot_unit/tests/scenario_stock_lot_unit.rst
@@ -0,0 +1,191 @@
+=======================
+Stock Lot Unit Scenario
+=======================
+
+Imports::
+
+ >>> import datetime
+ >>> from dateutil.relativedelta import relativedelta
+ >>> from decimal import Decimal
+ >>> from proteus import config, Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> today = datetime.date.today()
+
+Activate modules::
+
+ >>> config = activate_modules('stock_lot_unit')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create customer::
+
+ >>> Party = Model.get('party.party')
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+
+Create supplier::
+
+ >>> supplier = Party(name='Supplier')
+ >>> supplier.save()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template.lot_unit = unit
+ >>> template.save()
+ >>> product, = template.products
+ >>> product.cost_price = Decimal('8')
+ >>> product.save()
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> input_loc, = Location.find([('code', '=', 'IN')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+
+Create an incoming shipment without lot::
+
+ >>> ShipmentIn = Model.get('stock.shipment.in')
+ >>> shipment = ShipmentIn()
+ >>> shipment.supplier = supplier
+ >>> move1 = shipment.incoming_moves.new()
+ >>> move1.product = product
+ >>> move1.quantity = 60
+ >>> move1.unit_price = Decimal('8')
+ >>> move1.currency = company.currency
+ >>> move1.from_location = supplier_loc
+ >>> move1.to_location = input_loc
+ >>> move2 = shipment.incoming_moves.new()
+ >>> move2.product = product
+ >>> move2.quantity = 40
+ >>> move2.unit_price = Decimal('8')
+ >>> move2.currency = company.currency
+ >>> move2.from_location = supplier_loc
+ >>> move2.to_location = input_loc
+ >>> shipment.click('receive')
+ >>> shipment.click('done')
+
+Let's ship a product with a lot::
+
+ >>> Lot = Model.get('stock.lot')
+ >>> lot = Lot(number='00001', product=product)
+ >>> lot.unit == unit
+ True
+ >>> lot.unit_quantity
+ 1.0
+ >>> lot.save()
+
+ >>> ShipmentOut = Model.get('stock.shipment.out')
+ >>> shipment = ShipmentOut()
+ >>> shipment.customer = customer
+ >>> move = shipment.outgoing_moves.new()
+ >>> move.product = product
+ >>> move.quantity = 1
+ >>> move.unit_price = Decimal('20')
+ >>> move.currency = company.currency
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> shipment.click('wait')
+ >>> shipment.click('assign_try')
+ True
+ >>> move.lot = lot
+ >>> shipment.click('pick')
+ >>> shipment.click('pack')
+ >>> shipment.click('done')
+
+Let's ship now two times the same lot::
+
+ >>> lot = Lot(number='00002', product=product)
+ >>> lot.save()
+
+ >>> shipment = ShipmentOut()
+ >>> shipment.customer = customer
+ >>> move1 = shipment.outgoing_moves.new()
+ >>> move1.product = product
+ >>> move1.quantity = 1
+ >>> move1.unit_price = Decimal('20')
+ >>> move1.currency = company.currency
+ >>> move1.from_location = output_loc
+ >>> move1.to_location = customer_loc
+ >>> move2 = shipment.outgoing_moves.new()
+ >>> move2.product = product
+ >>> move2.quantity = 1
+ >>> move2.unit_price = Decimal('20')
+ >>> move2.currency = company.currency
+ >>> move2.from_location = output_loc
+ >>> move2.to_location = customer_loc
+ >>> shipment.click('wait')
+ >>> shipment.click('assign_try')
+ True
+ >>> move1, move2 = shipment.inventory_moves
+ >>> move1.lot = lot
+ >>> move2.lot = lot
+ >>> shipment.save()
+ >>> shipment.click('pick') # doctest: +IGNORE_EXCEPTION_DETAIL
+ Traceback (most recent call last):
+ ...
+ LotUnitQuantityError: ...
+
+Now let's ship one move with a quantity bigger than lot unit quantity::
+
+ >>> lot = Lot(number='00003', product=product)
+ >>> lot.unit_quantity = 3
+ >>> lot.save()
+
+ >>> shipment = ShipmentOut()
+ >>> shipment.customer = customer
+ >>> move = shipment.outgoing_moves.new()
+ >>> move.product = product
+ >>> move.quantity = 4
+ >>> move.unit_price = Decimal('20')
+ >>> move.currency = company.currency
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> shipment.click('wait')
+ >>> shipment.click('assign_try')
+ True
+ >>> move, = shipment.inventory_moves
+ >>> move.lot = lot
+ >>> shipment.click('pick') # doctest: +IGNORE_EXCEPTION_DETAIL
+ Traceback (most recent call last):
+ ...
+ LotUnitQuantityError: ...
+
+Make an inventory::
+
+ >>> lot = Lot(number='00004', product=product)
+ >>> lot.unit_quantity = 2
+ >>> lot.save()
+
+ >>> Inventory = Model.get('stock.inventory')
+ >>> inventory = Inventory()
+ >>> inventory.location = storage_loc
+ >>> line = inventory.lines.new()
+ >>> line.product = product
+ >>> line.lot = lot
+ >>> line.quantity = 3
+ >>> inventory.save()
+ >>> inventory.click('confirm') # doctest: +IGNORE_EXCEPTION_DETAIL
+ Traceback (most recent call last):
+ ...
+ LotUnitQuantityError: ...
+
+ >>> line, = inventory.lines
+ >>> line.quantity = 2
+ >>> inventory.click('confirm')
diff --git a/modules/stock_lot_unit/tests/scenario_stock_lot_unit_move_add.rst b/modules/stock_lot_unit/tests/scenario_stock_lot_unit_move_add.rst
new file mode 100644
index 0000000000..74f1a9801d
--- /dev/null
+++ b/modules/stock_lot_unit/tests/scenario_stock_lot_unit_move_add.rst
@@ -0,0 +1,75 @@
+================================
+Stock Lot Unit Move Add Scenario
+================================
+
+Imports::
+
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+
+Activate modules::
+
+ >>> config = activate_modules('stock_lot_unit')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template.save()
+ >>> product, = template.products
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+
+Create a move::
+
+ >>> Move = Model.get('stock.move')
+ >>> move = Move()
+ >>> move.from_location = storage_loc
+ >>> move.to_location = customer_loc
+ >>> move.product = product
+ >>> move.quantity = 5
+ >>> move.unit_price = Decimal('20')
+ >>> move.currency = company.currency
+ >>> move.save()
+
+Create a lot::
+
+ >>> Lot = Model.get('stock.lot')
+ >>> lot = Lot(number='01', product=product)
+ >>> lot.unit = unit
+ >>> lot.unit_quantity = 1
+ >>> lot.save()
+
+Add a lot::
+
+ >>> add_lots = Wizard('stock.move.add.lots', [move])
+ >>> lot = add_lots.form.lots.new()
+ >>> lot.quantity
+ 5.0
+ >>> lot.product = product # proteus does not set reverse domain
+ >>> lot.number = '01'
+ >>> lot.unit == unit
+ True
+ >>> lot.unit_quantity
+ 1.0
+ >>> lot.quantity
+ 1.0
diff --git a/modules/stock_lot_unit/tests/test_module.py b/modules/stock_lot_unit/tests/test_module.py
new file mode 100644
index 0000000000..0c20ccf123
--- /dev/null
+++ b/modules/stock_lot_unit/tests/test_module.py
@@ -0,0 +1,13 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockLotUnitTestCase(ModuleTestCase):
+ 'Test Stock Lot Unit module'
+ module = 'stock_lot_unit'
+ extras = ['production']
+
+
+del ModuleTestCase
diff --git a/modules/stock_lot_unit/tests/test_scenario.py b/modules/stock_lot_unit/tests/test_scenario.py
new file mode 100644
index 0000000000..dc1d23e7e5
--- /dev/null
+++ b/modules/stock_lot_unit/tests/test_scenario.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import load_doc_tests
+
+
+def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_lot_unit/tox.ini b/modules/stock_lot_unit/tox.ini
new file mode 100644
index 0000000000..eb3a1d6a76
--- /dev/null
+++ b/modules/stock_lot_unit/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_lot_unit/* -m unittest discover -s tests
+ coverage report --include=./**/stock_lot_unit/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_lot_unit/tryton.cfg b/modules/stock_lot_unit/tryton.cfg
new file mode 100644
index 0000000000..63b1795d5e
--- /dev/null
+++ b/modules/stock_lot_unit/tryton.cfg
@@ -0,0 +1,14 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ res
+ product
+ stock
+ stock_lot
+extras_depend:
+ production
+xml:
+ product.xml
+ stock.xml
+ message.xml
diff --git a/modules/stock_lot_unit/view/lot_form.xml b/modules/stock_lot_unit/view/lot_form.xml
new file mode 100644
index 0000000000..c01f8e1b22
--- /dev/null
+++ b/modules/stock_lot_unit/view/lot_form.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot_unit/view/lot_list.xml b/modules/stock_lot_unit/view/lot_list.xml
new file mode 100644
index 0000000000..25d4788b43
--- /dev/null
+++ b/modules/stock_lot_unit/view/lot_list.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_lot_unit/view/template_form.xml b/modules/stock_lot_unit/view/template_form.xml
new file mode 100644
index 0000000000..e302b3507f
--- /dev/null
+++ b/modules/stock_lot_unit/view/template_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package/.drone.yml b/modules/stock_package/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_package/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_package/.flake8 b/modules/stock_package/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_package/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_package/.isort.cfg b/modules/stock_package/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_package/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_package/CHANGELOG b/modules/stock_package/CHANGELOG
new file mode 100644
index 0000000000..229e80a85f
--- /dev/null
+++ b/modules/stock_package/CHANGELOG
@@ -0,0 +1,67 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Allow package type to be deactivated
+* Add volume dimensions to package
+* Filter out moves without quantity from package
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+* Remove dummy label report
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+* Include package weight to weight parcel
+* Add package weight
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+* Add open/closed state on package
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+* Check package also when packing shipment
+
+Version 4.2.0 - 2016-11-28
+* Bug fixes (see mercurial logs for details)
+
+Version 4.0.0 - 2016-05-02
+* Bug fixes (see mercurial logs for details)
+* Add Python3 support
+
+Version 3.8.0 - 2015-11-02
+* Bug fixes (see mercurial logs for details)
+
+Version 3.6.0 - 2015-04-20
+* Bug fixes (see mercurial logs for details)
+* Add support for PyPy
+Version 3.4.0 - 2014-10-20
+* Bug fixes (see mercurial logs for details)
+
+Version 3.2.0 - 2014-04-21
+* Initial release
diff --git a/modules/stock_package/COPYRIGHT b/modules/stock_package/COPYRIGHT
new file mode 100644
index 0000000000..983ad2cd2f
--- /dev/null
+++ b/modules/stock_package/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2013-2022 Cédric Krier.
+Copyright (C) 2013-2022 B2CK SPRL.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_package/LICENSE b/modules/stock_package/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_package/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_package/MANIFEST.in b/modules/stock_package/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_package/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_package/README.rst b/modules/stock_package/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_package/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_package/__init__.py b/modules/stock_package/__init__.py
new file mode 100644
index 0000000000..17f468e7ac
--- /dev/null
+++ b/modules/stock_package/__init__.py
@@ -0,0 +1,18 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import stock
+
+
+def register():
+ Pool.register(
+ stock.Configuration,
+ stock.ConfigurationSequence,
+ stock.Type,
+ stock.Package,
+ stock.Move,
+ stock.ShipmentOut,
+ stock.ShipmentInReturn,
+ module='stock_package', type_='model')
diff --git a/modules/stock_package/doc/index.rst b/modules/stock_package/doc/index.rst
new file mode 100644
index 0000000000..dadaff3115
--- /dev/null
+++ b/modules/stock_package/doc/index.rst
@@ -0,0 +1,13 @@
+Stock Package Module
+####################
+
+The stock package module allows to store packaging information about customer
+and supplier return shipments.
+
+Package
+*******
+
+A package groups together some moves from the same shipment.
+The packages can be organized in a tree structure.
+If a package is defined on a shipment, this one could be set to *Done* only if
+all moves are packaged.
diff --git a/modules/stock_package/exceptions.py b/modules/stock_package/exceptions.py
new file mode 100644
index 0000000000..5a473d8170
--- /dev/null
+++ b/modules/stock_package/exceptions.py
@@ -0,0 +1,13 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.exceptions import UserError
+from trytond.model.exceptions import ValidationError
+
+
+class PackageError(UserError):
+ pass
+
+
+class PackageValidationError(ValidationError):
+ pass
diff --git a/modules/stock_package/locale/bg.po b/modules/stock_package/locale/bg.po
new file mode 100644
index 0000000000..07bb701237
--- /dev/null
+++ b/modules/stock_package/locale/bg.po
@@ -0,0 +1,257 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "Наследници"
+
+#, fuzzy
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "Код"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "Движения"
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "Родител"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "Вид"
+
+#, fuzzy
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Условие за плащане"
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+#, fuzzy
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Package Types"
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/ca.po b/modules/stock_package/locale/ca.po
new file mode 100644
index 0000000000..b1f6e1a1a6
--- /dev/null
+++ b/modules/stock_package/locale/ca.po
@@ -0,0 +1,253 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr "Seqüència de paquet"
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr "Seqüència de paquet"
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr "Paquet"
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "Fills"
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "Codi"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "Moviments"
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr "Alçada del paquet"
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "UdM de l'alçada del paquet"
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr "Longitud del paquet"
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "UdM de la longitud del paquet"
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Volum del paquet"
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "UdM del volum del paquet"
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Pes del paquet"
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "UdM del pes del paquet"
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr "Amplada del paquet"
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "UdM de l'amplada del paquet"
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "Pare"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr "Albarà"
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr "Estat"
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "Tipus"
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Nom"
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr "Alçada del paquet"
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "UdM de l'alçada del paquet"
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr "Longitud del paquet"
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "UdM de la longitud del paquet"
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Volum del paquet"
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "UdM del volum del paquet"
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Pes del paquet"
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "UdM del pes del paquet"
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr "Amplada del paquet"
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "UdM de l'amplada del paquet"
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr "Paquets"
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr "Paquets"
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr "Paquets"
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr "Paquets"
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr "L'alçada del paquet."
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr "La longitud del paquet."
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr "El volum del paquet."
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr "El pes del paquet quan està buit."
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr "L'amplada del paquet."
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr "L'alçada del paquet."
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr "La longitud del paquet."
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr "El volum del paquet."
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr "El pes del paquet quan està buit."
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr "L'amplada del paquet."
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Tipus de paquet"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+"Per a processar l'albarà \"%(shipment)s\", heu d'empaquetar tots els seus "
+"moviments."
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+"El volum (%(volume)s) del paquet \"%(package)s\" és massa petit per al volum"
+" total (%(children_volume)s) dels seus paquets fills."
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr "Usuari a les empreses"
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Paquet"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Paquet"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Tipus de paquet"
+
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Paquet"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr "Tipus de paquet"
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr "Tancat"
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr "Obert"
+
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Paquet"
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr "Seqüència"
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr "Mesures"
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr "Mesures"
diff --git a/modules/stock_package/locale/cs.po b/modules/stock_package/locale/cs.po
new file mode 100644
index 0000000000..194689ace9
--- /dev/null
+++ b/modules/stock_package/locale/cs.po
@@ -0,0 +1,252 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr ""
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr ""
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr ""
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr ""
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Namu"
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+#, fuzzy
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Package Types"
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/de.po b/modules/stock_package/locale/de.po
new file mode 100644
index 0000000000..3d2f24d6c6
--- /dev/null
+++ b/modules/stock_package/locale/de.po
@@ -0,0 +1,254 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr "Nummernkreis Paket"
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr "Nummernkreis Paket"
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr "Paket"
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "Untergeordnet (Paket)"
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "Code"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr "Unternehmen"
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "Warenbewegungen"
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr "Verpackungshöhe"
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Maßeinheit Verpackungshöhe"
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr "Verpackungslänge"
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Maßeinheit Verpackungslänge"
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Verpackungsvolumen"
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Maßeinheit Verpackungsvolumen"
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Verpackungsgewicht"
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Maßeinheit Verpackungsgewicht"
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr "Verpackungsbreite"
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Maßeinheit Verpackungsbreite"
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "Übergeordnet (Paket)"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr "Lieferungen"
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr "Status"
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "Typ"
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Name"
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr "Verpackungshöhe"
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Maßeinheit Verpackungshöhe"
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr "Verpackungslänge"
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Maßeinheit Verpackungslänge"
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Verpackungsvolumen"
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Maßeinheit Verpackungsvolumen"
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Verpackungsgewicht"
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Maßeinheit Verpackungsgewicht"
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr "Verpackungsbreite"
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Maßeinheit Verpackungsbreite"
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr "Pakete"
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr "Pakete"
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr "Pakete"
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr "Pakete"
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr "Die Höhe der Verpackung."
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr "Die Länge der Verpackung."
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr "Das Volumen der Verpackung."
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr "Das Leergewicht der Verpackung."
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr "Die Breite der Verpackung."
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr "Die Höhe der Verpackung."
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr "Die Länge der Verpackung."
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr "Das Volumen der Verpackung."
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr "Das Leergewicht der Verpackung."
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr "Die Breite der Verpackung."
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Packstücktypen"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+"Damit die Lieferung \"%(shipment)s\" ausgeführt werden kann, müssen zuerst "
+"alle zugehörigen Warenbewegung gepackt werden."
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+"Das Volumen (%(volume)s) des Pakets \"%(package)s\" ist zu niedrig im "
+"Vergleich zum aufsummierten Volumen (%(children_volume)s) der "
+"untergeordneten Pakete."
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr "Benutzer im Unternehmen"
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Lager Paket"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Lager Paket"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Packstücktypen"
+
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Lager Paket"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr "Lager Packstücktyp"
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr "Geschlossen"
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr "Offen"
+
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Paket"
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr "Nummernkreis"
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr "Abmessungen"
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr "Abmessungen"
diff --git a/modules/stock_package/locale/es.po b/modules/stock_package/locale/es.po
new file mode 100644
index 0000000000..285a775e0b
--- /dev/null
+++ b/modules/stock_package/locale/es.po
@@ -0,0 +1,253 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr "Secuencia de paquete"
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr "Secuencia de paquete"
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr "Paquete"
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "Hijos"
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "Código"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "Movimientos"
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr "Altura del paquete"
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "UdM de la altura del paquete"
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr "Longitud del paquete"
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "UdM de la longitud del paquete"
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Volumen del paquete"
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "UdM del volumen del paquete"
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Peso del paquete"
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "UdM del peso del paquete"
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr "Ancho del paquete"
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "UdM del ancho del paquete"
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "Padre"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr "Albarán"
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr "Estado"
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "Tipo"
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Nombre"
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr "Altura del paquete"
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "UdM de la altura del paquete"
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr "Longitud del paquete"
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "UdM de la longitud del paquete"
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Volumen del paquete"
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "UdM del volumen del paquete"
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Peso del paquete"
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "UdM del peso del paquete"
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr "Ancho del paquete"
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "UdM del ancho del paquete"
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr "Paquetes"
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr "Paquetes"
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr "Paquetes"
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr "Paquetes"
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr "La altura del paquete."
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr "La longitud del paquete."
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr "El volumen del paquete."
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr "El peso del paquete cuando esta vacío."
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr "El ancho del paquete."
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr "La altura del paquete."
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr "La longitud del paquete."
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr "El volumen del paquete."
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr "El peso del paquete cuando esta vacío."
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr "El ancho del paquete."
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Tipos de paquete"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+"Para procesar el albarán \"%(shipment)s\", debe empaquetar todos sus "
+"movimientos."
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+"El volumen (%(volume)s) del paquete \"%(package)s\" es demasiado pequeño "
+"respecto el volumen total (%(children_volume)s) de sus paquetes hijos."
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr "Usuario en las empresas"
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Paquete"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Paquete"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Tipos de paquete"
+
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Paquete"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr "Tipo de paquete"
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr "Cerrado"
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr "Abierto"
+
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Paquete"
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr "Secuencia"
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr "Medidas"
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr "Medidas"
diff --git a/modules/stock_package/locale/es_419.po b/modules/stock_package/locale/es_419.po
new file mode 100644
index 0000000000..780276f826
--- /dev/null
+++ b/modules/stock_package/locale/es_419.po
@@ -0,0 +1,252 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr ""
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr ""
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr ""
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr ""
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr "Envío"
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Empaquetado de stock"
+
+#, fuzzy
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Empaquetado de stock"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr ""
+
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Empaquetado de stock"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr "Tipo de empaquetado de stock"
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Empaquetado de stock"
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/et.po b/modules/stock_package/locale/et.po
new file mode 100644
index 0000000000..4bce8bb708
--- /dev/null
+++ b/modules/stock_package/locale/et.po
@@ -0,0 +1,271 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr "Pakendamise jada"
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr "Pakendamise jada"
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr "Pakend"
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "Alamjaotus"
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "Kood"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "Kanded"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Pakend"
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "Ülemjaotus"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr "Tarne"
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr "Olek"
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "Tüüp"
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Nimi"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Pakend"
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr "Pakendid"
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr "Pakendid"
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr "Pakendid"
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr "Pakendid"
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Pakendi tüüp"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Laopakend"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Laopakend"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Pakendi tüüp"
+
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Laopakend"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr "Laopakendi tüüp"
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr "Suletud"
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr "Avatud"
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Pakend"
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr "Pakendamise jada"
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/fa.po b/modules/stock_package/locale/fa.po
new file mode 100644
index 0000000000..8e00d07fc9
--- /dev/null
+++ b/modules/stock_package/locale/fa.po
@@ -0,0 +1,273 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr "ادامه بسته"
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr "ادامه بسته"
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr "بسته"
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "زیر مجموعه"
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "کد"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "جابجایی ها"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "بسته"
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "منبع"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr "محموله"
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "نوع"
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "نام"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "بسته"
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr "بسته ها"
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr "بسته ها"
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr "بسته ها"
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr "بسته ها"
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "انواع بسته"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+"برای پردازش محموله :\"%(shipment)s\"، شما باید همه جابجایی های آن را بسته "
+"بندی کنید."
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "بسته کالا"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "بسته کالا"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "انواع بسته"
+
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "بسته کالا"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr "نوع بسته کالا"
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "بسته"
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr "ادامه بسته"
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/fi.po b/modules/stock_package/locale/fi.po
new file mode 100644
index 0000000000..4664a56f4d
--- /dev/null
+++ b/modules/stock_package/locale/fi.po
@@ -0,0 +1,251 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr ""
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr ""
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr ""
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr ""
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+#, fuzzy
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Package Types"
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/fr.po b/modules/stock_package/locale/fr.po
new file mode 100644
index 0000000000..2be950cd6e
--- /dev/null
+++ b/modules/stock_package/locale/fr.po
@@ -0,0 +1,253 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr "Séquence d'emballage"
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr "Séquence d'emballage"
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr "Emballage"
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "Enfants"
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "Code"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr "Société"
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "Mouvements"
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr "Hauteur de l'emballage"
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Hauteur de l'emballage UDM"
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr "Longueur de l'emballage"
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Longueur de l'emballage UDM"
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Volume de l'emballage"
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Volume de l'emballage UDM"
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Poids de l'emballage"
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Poids de l'emballage UDM"
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr "Largeur de l'emballage"
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Largeur de l'emballage UDM"
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "Parent"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr "Expédition"
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr "État"
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "Type"
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Nom"
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr "Hauteur de l'emballage"
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Hauteur de l'emballage UDM"
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr "Longueur de l'emballage"
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Longueur de l'emballage UDM"
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Volume de l'emballage"
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Volume de l'emballage UDM"
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Poids de l'emballage"
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Poids de l'emballage UDM"
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr "Largeur de l'emballage"
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Largeur de l'emballage UDM"
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr "Emballages"
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr "Emballages"
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr "Emballages"
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr "Emballages"
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr "La hauteur de l'emballage."
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr "La longueur de l'emballage."
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr "Le volume de l'emballage."
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr "Le poids du colis vide."
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr "La largeur de l'emballage."
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr "La hauteur de l'emballage."
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr "La longueur de l'emballage."
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr "Le volume de l'emballage."
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr "Le poids du colis vide."
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr "La largeur de l'emballage."
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Types d'emballage"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+"Pour traiter l’expédition « %(shipment)s », vous devez emballer tous ces "
+"mouvements."
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+"Le volume (%(volume)s) de l'emballage « %(package)s » est trop petit pour le"
+" volume additionné (%(children_volume)s) de ses colis enfants."
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr "Utilisateur dans les sociétés"
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Emballage de stock"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Emballage de stock"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Types d'emballage"
+
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Emballage de stock"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr "Type d'emballage de stock"
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr "Fermé"
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr "Ouvert"
+
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Emballage"
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr "Séquence"
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr "Mesures"
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr "Mesures"
diff --git a/modules/stock_package/locale/hu.po b/modules/stock_package/locale/hu.po
new file mode 100644
index 0000000000..fbc6f56794
--- /dev/null
+++ b/modules/stock_package/locale/hu.po
@@ -0,0 +1,276 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr "Csomag számkör"
+
+#, fuzzy
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr "Csomag számkör"
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr "Csomag"
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "Gyermek (csomag)"
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "Kód"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "Raktár mozgatás"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Csomag"
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "Szülő (csomag)"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr "Szállítási tétel"
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "Típus"
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Név"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Csomag"
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr "Csomagok"
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr "Csomagok"
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr "Csomagok"
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr "Csomagok"
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+#, fuzzy
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Raktár csomag"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr "Raktár csomag típus"
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Csomag"
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr "Csomag számkör"
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/id.po b/modules/stock_package/locale/id.po
new file mode 100644
index 0000000000..866e489bac
--- /dev/null
+++ b/modules/stock_package/locale/id.po
@@ -0,0 +1,249 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr ""
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "Cabang"
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "Kode"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr "Perusahaan"
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "Perpindahan"
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "Induk"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Nama"
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr ""
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr ""
+
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr ""
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr "Buka"
+
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr "Urutan"
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/it.po b/modules/stock_package/locale/it.po
new file mode 100644
index 0000000000..0bdd108f22
--- /dev/null
+++ b/modules/stock_package/locale/it.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "Figlio"
+
+#, fuzzy
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "Codice"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "Movimenti"
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "Padre"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr "Stato"
+
+#, fuzzy
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "Tipo"
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Nome"
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+#, fuzzy
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Package Types"
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/lo.po b/modules/stock_package/locale/lo.po
new file mode 100644
index 0000000000..bbc64154d4
--- /dev/null
+++ b/modules/stock_package/locale/lo.po
@@ -0,0 +1,257 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "ໝວດຍ່ອຍ"
+
+#, fuzzy
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "ລະຫັດແຂວງ"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "ຕັດບັນຊີສາງ"
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "ຮ່ວງ"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "ຮູບແບບ"
+
+#, fuzzy
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "ຊື່"
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+#, fuzzy
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Package Types"
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/lt.po b/modules/stock_package/locale/lt.po
new file mode 100644
index 0000000000..194689ace9
--- /dev/null
+++ b/modules/stock_package/locale/lt.po
@@ -0,0 +1,252 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr ""
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr ""
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr ""
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr ""
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Namu"
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+#, fuzzy
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Package Types"
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/nl.po b/modules/stock_package/locale/nl.po
new file mode 100644
index 0000000000..96f5fb2b7d
--- /dev/null
+++ b/modules/stock_package/locale/nl.po
@@ -0,0 +1,253 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr "Pakketvolgorde"
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr "Pakketvolgorde"
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr "Pakket"
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "Onderliggende niveaus"
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "Code"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr "Bedrijf"
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "Mutaties"
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr "Hoogte verpakking"
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Maateenheid hoogte verpakking"
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr "Lengte verpakking"
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Maateenheid lengte verpakking"
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Volume verpakking"
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Maateenheid volume verpakking"
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Gewicht verpakking"
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Maateenheid gewicht verpakking"
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr "Breedte verpakking"
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Maateenheid breedte verpakking"
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "Bovenliggend niveau"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr "Levering"
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr "Status"
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "Type"
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Naam"
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr "Hoogte verpakking"
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Maateenheid hoogte verpakking"
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr "Lengte verpakking"
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Maateenheid lengte verpakking"
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Volume verpakking"
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Maateenheid volume verpakking"
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Gewicht verpakking"
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Maateenheid gewicht verpakking"
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr "Breedte verpakking"
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Maateenheid breedte verpakking"
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr "Pakketten"
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr "Pakketten"
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr "Pakketten"
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr "Pakketten"
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr "De hoogte van de verpakking."
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr "De lengte van de verpakking."
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr "Het volume van de verpakking."
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr "Het gewicht van de lege verpakking."
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr "De breedte van de verpakking."
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr "De hoogte van de verpakking."
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr "De lengte van de verpakking."
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr "Het volume van de verpakking."
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr "Het gewicht van de lege verpakking."
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr "De breedte van de verpakking."
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Pakket Soorten"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+"Om zending \"%(shipment)s\" te verwerken, moet u alle voorraadmutaties "
+"inpakken."
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+"Het volume (%(volume)s) van verpakking \"%(package)s\" is te klein voor het "
+"totale volume (%(children_volume)s) van de onderliggende verpakkingen."
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr "Gebruiker in het bedrijf"
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Voorraad Verpakking"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Voorraad Verpakking"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Pakket Soorten"
+
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Voorraad Verpakking"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr "Voorraad Pakket Soort"
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr "Afgesloten"
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr "Open"
+
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Verpakking"
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr "Reeks"
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr "Afmetingen"
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr "Afmetingen"
diff --git a/modules/stock_package/locale/pl.po b/modules/stock_package/locale/pl.po
new file mode 100644
index 0000000000..6a0c5d1efb
--- /dev/null
+++ b/modules/stock_package/locale/pl.po
@@ -0,0 +1,276 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr "Sekwencja paczki"
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr "Sekwencja paczki"
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr "Paczka"
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "Podrzędne paczki"
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "Kod"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "Ruchy"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Paczka"
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "Paczka nadrzędna"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr "Wysyłka"
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "Typ"
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Nazwa"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Paczka"
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr "Paczki"
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr "Paczki"
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr "Paczki"
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr "Paczki"
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+#, fuzzy
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+#, fuzzy
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Paczka"
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr "Sekwencja paczki"
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/pt.po b/modules/stock_package/locale/pt.po
new file mode 100644
index 0000000000..0677caf38b
--- /dev/null
+++ b/modules/stock_package/locale/pt.po
@@ -0,0 +1,275 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr "Sequência das Embalagens"
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr "Sequência dos Pacotes"
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr "Pacote"
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "Filhos"
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "Código"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "Movimentações"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Pacote"
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "Pai"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr "Remessa"
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "Tipo"
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Nome"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Pacote"
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr "Pacotes"
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr "Pacotes"
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr "Pacotes"
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr "Pacotes"
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+#, fuzzy
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Estoque de Pacote"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr "Tipo de Estoque de Pacote"
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Pacote"
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr "Sequência das Embalagens"
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/ro.po b/modules/stock_package/locale/ro.po
new file mode 100644
index 0000000000..f44f6b29db
--- /dev/null
+++ b/modules/stock_package/locale/ro.po
@@ -0,0 +1,249 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr ""
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "Copii"
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "Cod"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "Părinte"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr "Expediere"
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr ""
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr ""
+
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr ""
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr "Închis"
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr "Secvenţă"
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/ru.po b/modules/stock_package/locale/ru.po
new file mode 100644
index 0000000000..8ec21e585c
--- /dev/null
+++ b/modules/stock_package/locale/ru.po
@@ -0,0 +1,258 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "Подчиненый"
+
+#, fuzzy
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "Код языка"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "Перемещения"
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "Предок"
+
+#, fuzzy
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr "Доставка"
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "Тип"
+
+#, fuzzy
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Правило оплаты"
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+#, fuzzy
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Package Types"
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/sl.po b/modules/stock_package/locale/sl.po
new file mode 100644
index 0000000000..f62909b36a
--- /dev/null
+++ b/modules/stock_package/locale/sl.po
@@ -0,0 +1,275 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr "Štetje paketov"
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr "Štetje paketov"
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr "Paket"
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "Podpaketi"
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "Šifra"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr "Promet"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Paket"
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "Matični paket"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr "Pošiljka"
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "Tip"
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "Naziv"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr "Paket"
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr "Paketi"
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr "Paketi"
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr "Paketi"
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr "Paketi"
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+#, fuzzy
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Paket"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr "Vrsta paketa"
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Paket"
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr "Štetje paketov"
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/tr.po b/modules/stock_package/locale/tr.po
new file mode 100644
index 0000000000..4664a56f4d
--- /dev/null
+++ b/modules/stock_package/locale/tr.po
@@ -0,0 +1,251 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr ""
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr ""
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr ""
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr ""
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+#, fuzzy
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Package Types"
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/uk.po b/modules/stock_package/locale/uk.po
new file mode 100644
index 0000000000..34465616a2
--- /dev/null
+++ b/modules/stock_package/locale/uk.po
@@ -0,0 +1,249 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr ""
+
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr ""
+
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr ""
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr ""
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr ""
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr ""
+
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr ""
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/locale/zh_CN.po b/modules/stock_package/locale/zh_CN.po
new file mode 100644
index 0000000000..84be1dbca7
--- /dev/null
+++ b/modules/stock_package/locale/zh_CN.po
@@ -0,0 +1,256 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.configuration.sequence,package_sequence:"
+msgid "Package Sequence"
+msgstr ""
+
+msgctxt "field:stock.move,package:"
+msgid "Package"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,children:"
+msgid "Children"
+msgstr "子项"
+
+#, fuzzy
+msgctxt "field:stock.package,code:"
+msgid "Code"
+msgstr "语言编码"
+
+msgctxt "field:stock.package,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.package,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,parent:"
+msgid "Parent"
+msgstr "上级"
+
+msgctxt "field:stock.package,shipment:"
+msgid "Shipment"
+msgstr ""
+
+msgctxt "field:stock.package,state:"
+msgid "State"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,type:"
+msgid "Type"
+msgstr "类型"
+
+#, fuzzy
+msgctxt "field:stock.package.type,name:"
+msgid "Name"
+msgstr "纳木"
+
+msgctxt "field:stock.package.type,packaging_height:"
+msgid "Packaging Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_height_uom:"
+msgid "Packaging Height UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length:"
+msgid "Packaging Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_length_uom:"
+msgid "Packaging Length UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume:"
+msgid "Packaging Volume"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_volume_uom:"
+msgid "Packaging Volume UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight:"
+msgid "Packaging Weight"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_weight_uom:"
+msgid "Packaging Weight UOM"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width:"
+msgid "Packaging Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,packaging_width_uom:"
+msgid "Packaging Width UOM"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,root_packages:"
+msgid "Packages"
+msgstr ""
+
+msgctxt "help:stock.package,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_height:"
+msgid "The height of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_length:"
+msgid "The length of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_volume:"
+msgid "The volume of the package."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_weight:"
+msgid "The weight of the package when empty."
+msgstr ""
+
+msgctxt "help:stock.package.type,packaging_width:"
+msgid "The width of the package."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_package_type_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+msgctxt "model:ir.message,text:msg_package_mismatch"
+msgid "To process shipment \"%(shipment)s\", you must pack all its moves."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_package_volume_too_small"
+msgid ""
+"The volume (%(volume)s) of package \"%(package)s\" is too small for summed "
+"volume (%(children_volume)s) of its children packages."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_package_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.sequence,name:sequence_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.sequence.type,name:sequence_type_package"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:ir.ui.menu,name:menu_package_form"
+msgid "Package Types"
+msgstr "Package Types"
+
+#, fuzzy
+msgctxt "model:stock.package,name:"
+msgid "Stock Package"
+msgstr "Stock Package"
+
+msgctxt "model:stock.package.type,name:"
+msgid "Stock Package Type"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.package,state:"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Package"
+msgstr "Package Types"
+
+msgctxt "view:stock.configuration:"
+msgid "Sequence"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.package:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_package/message.xml b/modules/stock_package/message.xml
new file mode 100644
index 0000000000..e5cf5e964c
--- /dev/null
+++ b/modules/stock_package/message.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+ To process shipment "%(shipment)s", you must pack all its moves.
+
+
+ The volume (%(volume)s) of package "%(package)s" is too small for summed volume (%(children_volume)s) of its children packages.
+
+
+
diff --git a/modules/stock_package/setup.py b/modules/stock_package/setup.py
new file mode 100755
index 0000000000..4751817723
--- /dev/null
+++ b/modules/stock_package/setup.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_package'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = ['python-sql']
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [get_require_version('proteus')]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module for stock packaging',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_package',
+ },
+ keywords='tryton stock packaging',
+ package_dir={'trytond.modules.stock_package': '.'},
+ packages=(
+ ['trytond.modules.stock_package']
+ + ['trytond.modules.stock_package.%s' % p for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_package': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'Intended Audience :: Manufacturing',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_package = trytond.modules.stock_package
+ """,
+ )
diff --git a/modules/stock_package/stock.py b/modules/stock_package/stock.py
new file mode 100644
index 0000000000..0d24d77cb0
--- /dev/null
+++ b/modules/stock_package/stock.py
@@ -0,0 +1,528 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from sql import Cast, Literal
+from sql.functions import CharLength, Position, Substring
+
+from trytond import backend
+from trytond.i18n import gettext
+from trytond.model import (
+ DeactivableMixin, ModelSQL, ModelView, Workflow, fields, tree)
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Bool, Eval, Id, If
+from trytond.transaction import Transaction
+
+from .exceptions import PackageError, PackageValidationError
+
+
+class Configuration(metaclass=PoolMeta):
+ __name__ = 'stock.configuration'
+ package_sequence = fields.MultiValue(fields.Many2One(
+ 'ir.sequence', "Package Sequence", required=True,
+ domain=[
+ ('company', 'in', [
+ Eval('context', {}).get('company', -1), None]),
+ ('sequence_type', '=',
+ Id('stock_package', 'sequence_type_package')),
+ ]))
+
+ @classmethod
+ def multivalue_model(cls, field):
+ pool = Pool()
+ if field == 'package_sequence':
+ return pool.get('stock.configuration.sequence')
+ return super(Configuration, cls).multivalue_model(field)
+
+ @classmethod
+ def default_package_sequence(cls, **pattern):
+ return cls.multivalue_model(
+ 'package_sequence').default_package_sequence()
+
+
+class ConfigurationSequence(metaclass=PoolMeta):
+ __name__ = 'stock.configuration.sequence'
+ package_sequence = fields.Many2One(
+ 'ir.sequence', "Package Sequence", required=True,
+ domain=[
+ ('company', 'in', [Eval('company', -1), None]),
+ ('sequence_type', '=',
+ Id('stock_package', 'sequence_type_package')),
+ ])
+
+ @classmethod
+ def __register__(cls, module_name):
+ exist = backend.TableHandler.table_exist(cls._table)
+ if exist:
+ table = cls.__table_handler__(module_name)
+ exist &= table.column_exist('package_sequence')
+
+ super(ConfigurationSequence, cls).__register__(module_name)
+
+ if not exist:
+ cls._migrate_property([], [], [])
+
+ @classmethod
+ def _migrate_property(cls, field_names, value_names, fields):
+ field_names.append('package_sequence')
+ value_names.append('package_sequence')
+ super(ConfigurationSequence, cls)._migrate_property(
+ field_names, value_names, fields)
+
+ @classmethod
+ def default_package_sequence(cls):
+ pool = Pool()
+ ModelData = pool.get('ir.model.data')
+ try:
+ return ModelData.get_id('stock_package', 'sequence_package')
+ except KeyError:
+ return None
+
+
+class MeasurementsMixin:
+ __slots__ = ()
+
+ packaging_length = fields.Float(
+ "Packaging Length", digits='packaging_length_uom',
+ help="The length of the package.")
+ packaging_length_uom = fields.Many2One(
+ 'product.uom', "Packaging Length UOM",
+ domain=[('category', '=', Id('product', 'uom_cat_length'))],
+ states={
+ 'required': Bool(Eval('packaging_length')),
+ },
+ depends=['packaging_length'])
+ packaging_height = fields.Float(
+ "Packaging Height", digits='packaging_height_uom',
+ help="The height of the package.")
+ packaging_height_uom = fields.Many2One(
+ 'product.uom', "Packaging Height UOM",
+ domain=[('category', '=', Id('product', 'uom_cat_length'))],
+ states={
+ 'required': Bool(Eval('packaging_height')),
+ },
+ depends=['packaging_height'])
+ packaging_width = fields.Float(
+ "Packaging Width", digits='packaging_width_uom',
+ help="The width of the package.")
+ packaging_width_uom = fields.Many2One(
+ 'product.uom', "Packaging Width UOM",
+ domain=[('category', '=', Id('product', 'uom_cat_length'))],
+ states={
+ 'required': Bool(Eval('packaging_width')),
+ },
+ depends=['packaging_width'])
+
+ packaging_volume = fields.Float(
+ "Packaging Volume", digits='packaging_volume_uom',
+ states={
+ 'readonly': (
+ Bool(Eval('packaging_length'))
+ & Bool(Eval('packaging_height'))
+ & Bool(Eval('packaging_width'))),
+ },
+ depends=['packaging_length', 'packaging_height', 'packaging_width'],
+ help="The volume of the package.")
+ packaging_volume_uom = fields.Many2One(
+ 'product.uom', "Packaging Volume UOM",
+ domain=[('category', '=', Id('product', 'uom_cat_volume'))],
+ states={
+ 'required': Bool(Eval('packaging_volume')),
+ },
+ depends=['packaging_volume'])
+
+ packaging_weight = fields.Float(
+ "Packaging Weight", digits='packaging_weight_uom',
+ help="The weight of the package when empty.")
+ packaging_weight_uom = fields.Many2One(
+ 'product.uom', "Packaging Weight UOM",
+ domain=[('category', '=', Id('product', 'uom_cat_weight'))],
+ states={
+ 'required': Bool(Eval('packaging_weight')),
+ })
+
+ @fields.depends(
+ 'packaging_volume', 'packaging_volume_uom',
+ 'packaging_length', 'packaging_length_uom',
+ 'packaging_height', 'packaging_height_uom',
+ 'packaging_width', 'packaging_width_uom')
+ def on_change_with_packaging_volume(self):
+ pool = Pool()
+ ModelData = pool.get('ir.model.data')
+ Uom = pool.get('product.uom')
+
+ if not all([self.packaging_volume_uom,
+ self.packaging_length, self.packaging_length_uom,
+ self.packaging_height, self.packaging_height_uom,
+ self.packaging_width, self.packaging_width_uom]):
+ if all([
+ self.packaging_length,
+ self.packaging_height,
+ self.packaging_width]):
+ return
+ return self.packaging_volume
+
+ meter = Uom(ModelData.get_id('product', 'uom_meter'))
+ cubic_meter = Uom(ModelData.get_id('product', 'uom_cubic_meter'))
+
+ length = Uom.compute_qty(
+ self.packaging_length_uom, self.packaging_length, meter,
+ round=False)
+ height = Uom.compute_qty(
+ self.packaging_height_uom, self.packaging_height, meter,
+ round=False)
+ width = Uom.compute_qty(
+ self.packaging_width_uom, self.packaging_width, meter,
+ round=False)
+
+ return Uom.compute_qty(
+ cubic_meter, length * height * width, self.packaging_volume_uom)
+
+
+class Package(tree(), MeasurementsMixin, ModelSQL, ModelView):
+ 'Stock Package'
+ __name__ = 'stock.package'
+ _rec_name = 'code'
+ code = fields.Char('Code', readonly=True, required=True)
+ company = fields.Many2One('company.company', "Company", required=True)
+ type = fields.Many2One(
+ 'stock.package.type', "Type", required=True,
+ states={
+ 'readonly': Eval('state') == 'closed',
+ })
+ shipment = fields.Reference(
+ "Shipment", selection='get_shipment',
+ states={
+ 'readonly': Eval('state') == 'closed',
+ },
+ domain={
+ 'stock.shipment.out': [
+ ('company', '=', Eval('company', -1)),
+ ],
+ 'stock.shipment.in.return': [
+ ('company', '=', Eval('company', -1)),
+ ],
+ })
+ moves = fields.One2Many('stock.move', 'package', 'Moves',
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ('shipment', '=', Eval('shipment')),
+ ('to_location.type', 'in', ['customer', 'supplier']),
+ ('state', '!=', 'cancelled'),
+ ],
+ filter=[
+ ('quantity', '!=', 0),
+ ],
+ add_remove=[
+ ('package', '=', None),
+ ],
+ states={
+ 'readonly': Eval('state') == 'closed',
+ })
+ parent = fields.Many2One(
+ 'stock.package', "Parent", ondelete='CASCADE',
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ('shipment', '=', Eval('shipment')),
+ ],
+ states={
+ 'readonly': Eval('state') == 'closed',
+ })
+ children = fields.One2Many(
+ 'stock.package', 'parent', 'Children',
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ('shipment', '=', Eval('shipment')),
+ ],
+ states={
+ 'readonly': Eval('state') == 'closed',
+ })
+ state = fields.Function(fields.Selection([
+ ('open', "Open"),
+ ('closed', "Closed"),
+ ], "State"), 'on_change_with_state')
+
+ @classmethod
+ def __setup__(cls):
+ cls.code.search_unaccented = False
+ super().__setup__()
+
+ @classmethod
+ def __register__(cls, module):
+ pool = Pool()
+ table_h = cls.__table_handler__(module)
+ table = cls.__table__()
+ company_exist = table_h.column_exist('company')
+ cursor = Transaction().connection.cursor()
+
+ super().__register__(module)
+
+ # Migration from 5.8: add company
+ if not company_exist:
+ shipment_id = Cast(Substring(
+ table.shipment,
+ Position(',', table.shipment) + Literal(1)),
+ cls.id.sql_type().base)
+ for name in cls._get_shipment():
+ Shipment = pool.get(name)
+ shipment = Shipment.__table__()
+ value = (shipment
+ .select(shipment.company,
+ where=shipment.id == shipment_id))
+ cursor.execute(*table.update(
+ [table.company], [value],
+ where=table.shipment.like(name + ',%')))
+
+ @classmethod
+ def order_code(cls, tables):
+ table, _ = tables[None]
+ return [CharLength(table.code), table.code]
+
+ @classmethod
+ def default_company(cls):
+ return Transaction().context.get('company')
+
+ @staticmethod
+ def _get_shipment():
+ 'Return list of Model names for shipment Reference'
+ return [
+ 'stock.shipment.out',
+ 'stock.shipment.in.return',
+ ]
+
+ @classmethod
+ def get_shipment(cls):
+ pool = Pool()
+ Model = pool.get('ir.model')
+ get_name = Model.get_name
+ models = cls._get_shipment()
+ return [(None, '')] + [(m, get_name(m)) for m in models]
+
+ @fields.depends('shipment')
+ def on_change_with_state(self, name=None):
+ if (self.shipment
+ and self.shipment.state in {'packed', 'done', 'cancelled'}):
+ return 'closed'
+ return 'open'
+
+ @fields.depends('type')
+ def on_change_type(self):
+ if self.type:
+ for name in dir(MeasurementsMixin):
+ if isinstance(getattr(MeasurementsMixin, name), fields.Field):
+ setattr(self, name, getattr(self.type, name))
+
+ @classmethod
+ def validate(cls, packages):
+ super().validate(packages)
+ for package in packages:
+ package.check_volume()
+
+ def check_volume(self):
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ Lang = pool.get('ir.lang')
+ lang = Lang.get()
+ if not self.packaging_volume:
+ return
+ children_volume = 0
+ for child in self.children:
+ if child.packaging_volume:
+ children_volume += Uom.compute_qty(
+ child.packaging_volume_uom, child.packaging_volume,
+ self.packaging_volume_uom, round=False)
+ if self.packaging_volume < children_volume:
+ raise PackageValidationError(
+ gettext('stock_package.msg_package_volume_too_small',
+ package=self.rec_name,
+ volume=lang.format_number_symbol(
+ self.packaging_volume, self.packaging_volume_uom),
+ children_volume=lang.format_number_symbol(
+ children_volume, self.packaging_volume_uom)))
+
+ @classmethod
+ def create(cls, vlist):
+ pool = Pool()
+ Config = pool.get('stock.configuration')
+
+ vlist = [v.copy() for v in vlist]
+ config = Config(1)
+ default_company = cls.default_company()
+ for values in vlist:
+ values['code'] = config.get_multivalue(
+ 'package_sequence',
+ company=values.get('company', default_company)).get()
+ return super(Package, cls).create(vlist)
+
+ @classmethod
+ def copy(cls, packages, default=None):
+ if default is None:
+ default = {}
+ else:
+ default = default.copy()
+ default.setdefault('moves')
+ return super().copy(packages, default=default)
+
+
+class Type(MeasurementsMixin, DeactivableMixin, ModelSQL, ModelView):
+ 'Stock Package Type'
+ __name__ = 'stock.package.type'
+ name = fields.Char('Name', required=True)
+
+
+class Move(metaclass=PoolMeta):
+ __name__ = 'stock.move'
+ package = fields.Many2One(
+ 'stock.package', "Package", readonly=True,
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ],
+ states={
+ 'readonly': Eval('state') == 'cancelled',
+ })
+
+ @property
+ def package_path(self):
+ path = []
+ package = self.package
+ while package:
+ path.append(package)
+ package = package.parent
+ path.reverse()
+ return path
+
+ @classmethod
+ def copy(cls, moves, default=None):
+ if default is None:
+ default = {}
+ else:
+ default = default.copy()
+ default.setdefault('package')
+ return super().copy(moves, default=default)
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('cancelled')
+ def cancel(cls, moves):
+ cls.write([m for m in moves if m.package], {'package': None})
+ super().cancel(moves)
+
+
+class PackageMixin(object):
+ __slots__ = ()
+ packages = fields.One2Many('stock.package', 'shipment', 'Packages',
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ])
+ root_packages = fields.Function(fields.One2Many('stock.package',
+ 'shipment', 'Packages',
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ('parent', '=', None),
+ ]),
+ 'get_root_packages', setter='set_root_packages')
+
+ def get_root_packages(self, name):
+ return [p.id for p in self.packages if not p.parent]
+
+ @classmethod
+ def set_root_packages(cls, shipments, name, value):
+ if not value:
+ return
+ cls.write(shipments, {
+ 'packages': value,
+ })
+
+ @classmethod
+ def check_packages(cls, shipments):
+ for shipment in shipments:
+ if not shipment.packages:
+ continue
+ length = sum(len(p.moves) for p in shipment.packages)
+ if len(shipment.packages_moves) != length:
+ raise PackageError(
+ gettext('stock_package.msg_package_mismatch',
+ shipment=shipment.rec_name))
+
+ @property
+ def packages_moves(self):
+ raise NotImplementedError
+
+
+class ShipmentOut(PackageMixin, object, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out'
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ packages_readonly = If(
+ Eval('warehouse_storage') == Eval('warehouse_output'),
+ Eval('state') != 'waiting',
+ Eval('state') != 'picked')
+ for field in [cls.packages, cls.root_packages]:
+ field.states['readonly'] = packages_readonly
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('packed')
+ def pack(cls, shipments):
+ super(ShipmentOut, cls).pack(shipments)
+ cls.check_packages(shipments)
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('done')
+ def done(cls, shipments):
+ super(ShipmentOut, cls).done(shipments)
+ cls.check_packages(shipments)
+
+ @property
+ def packages_moves(self):
+ return [
+ m for m in self.outgoing_moves
+ if m.state != 'cancelled' and m.quantity]
+
+ def _group_parcel_key(self, lines, line):
+ try:
+ root_package = line.package_path[0]
+ except IndexError:
+ root_package = None
+ return super()._group_parcel_key(lines, line) + (
+ ('root_package', root_package),)
+
+ @fields.depends('carrier')
+ def _parcel_weight(self, parcel):
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ weight = super()._parcel_weight(parcel)
+ if self.carrier:
+ carrier_uom = self.carrier.weight_uom
+ packages = {p for l in parcel for p in l.package_path}
+ for package in packages:
+ if package.packaging_weight:
+ weight += Uom.compute_qty(
+ package.packaging_weight_uom, package.packaging_weight,
+ carrier_uom, round=False)
+ return weight
+
+
+class ShipmentInReturn(PackageMixin, object, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in.return'
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ packages_readonly = ~Eval('state').in_(['waiting', 'assigned'])
+ for field in [cls.packages, cls.root_packages]:
+ field.states['readonly'] = packages_readonly
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('done')
+ def done(cls, shipments):
+ super(ShipmentInReturn, cls).done(shipments)
+ cls.check_packages(shipments)
+
+ @property
+ def packages_moves(self):
+ return [
+ m for m in self.moves
+ if m.state != 'cancelled' and m.quantity]
diff --git a/modules/stock_package/stock.xml b/modules/stock_package/stock.xml
new file mode 100644
index 0000000000..71123c23c3
--- /dev/null
+++ b/modules/stock_package/stock.xml
@@ -0,0 +1,148 @@
+
+
+
+
+
+ Stock Package
+
+
+
+
+
+
+
+
+
+
+
+ Stock Package
+
+
+
+
+ stock.configuration
+
+ configuration_form
+
+
+
+ stock.package
+ form
+ package_form
+
+
+
+ stock.package
+ tree
+ children
+ package_tree
+
+
+
+ stock.package
+ tree
+ package_list
+
+
+
+ User in companies
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ stock.package.type
+ form
+ package_type_form
+
+
+
+ stock.package.type
+ tree
+ package_type_list
+
+
+
+ Package Types
+ stock.package.type
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ stock.move
+
+ stock_move_form
+
+
+
+ stock.shipment.out
+
+ shipment_out_form
+
+
+
+ stock.shipment.in.return
+
+ shipment_in_return_form
+
+
+
diff --git a/modules/stock_package/tests/__init__.py b/modules/stock_package/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_package/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_package/tests/scenario_stock_package.rst b/modules/stock_package/tests/scenario_stock_package.rst
new file mode 100644
index 0000000000..1e88c98b48
--- /dev/null
+++ b/modules/stock_package/tests/scenario_stock_package.rst
@@ -0,0 +1,130 @@
+======================
+Stock Package Scenario
+======================
+
+Imports::
+
+ >>> import datetime
+ >>> from dateutil.relativedelta import relativedelta
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.exceptions import UserError
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> today = datetime.date.today()
+
+Activate modules::
+
+ >>> config = activate_modules('stock_package')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create customer::
+
+ >>> Party = Model.get('party.party')
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template.save()
+ >>> product, = template.products
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+
+Create Shipment Out::
+
+ >>> ShipmentOut = Model.get('stock.shipment.out')
+ >>> shipment_out = ShipmentOut()
+ >>> shipment_out.planned_date = today
+ >>> shipment_out.customer = customer
+ >>> shipment_out.warehouse = warehouse_loc
+ >>> shipment_out.company = company
+
+Add two shipment lines of same product::
+
+ >>> StockMove = Model.get('stock.move')
+ >>> shipment_out.outgoing_moves.extend([StockMove(), StockMove()])
+ >>> for move in shipment_out.outgoing_moves:
+ ... move.product = product
+ ... move.uom =unit
+ ... move.quantity = 1
+ ... move.from_location = output_loc
+ ... move.to_location = customer_loc
+ ... move.company = company
+ ... move.unit_price = Decimal('1')
+ ... move.currency = company.currency
+ >>> shipment_out.save()
+
+Pack shipment::
+
+ >>> shipment_out.click('wait')
+ >>> shipment_out.click('assign_force')
+ >>> shipment_out.click('pick')
+
+Package products::
+
+ >>> PackageType = Model.get('stock.package.type')
+ >>> box = PackageType(name='box')
+ >>> box.packaging_length = 80
+ >>> box.packaging_length_uom, = ProductUom.find([('name', '=', "Centimeter")])
+ >>> box.packaging_width = 1
+ >>> box.packaging_width_uom, = ProductUom.find([('name', '=', "Meter")])
+ >>> box.packaging_height_uom = box.packaging_length_uom
+ >>> box.packaging_volume
+ >>> box.packaging_volume_uom, = ProductUom.find([('name', '=', "Cubic meter")])
+ >>> box.save()
+ >>> package1 = shipment_out.packages.new(type=box)
+ >>> package1.packaging_length
+ 80.0
+ >>> package1.packaging_height = 50
+ >>> package1.packaging_volume
+ 0.4
+ >>> package_child = package1.children.new(shipment=shipment_out, type=box)
+ >>> package_child.packaging_height = 100
+ >>> moves = package_child.moves.find()
+ >>> len(moves)
+ 2
+ >>> package_child.moves.append(moves[0])
+
+ >>> shipment_out.save() # doctest: +IGNORE_EXCEPTION_DETAIL
+ Traceback (most recent call last):
+ ...
+ PackageValidationError: ...
+
+ >>> package1.packaging_height = 120
+ >>> package1.packaging_volume
+ 0.96
+
+ >>> shipment_out.click('pack') # doctest: +IGNORE_EXCEPTION_DETAIL
+ Traceback (most recent call last):
+ ...
+ PackageError: ...
+
+ >>> package2 = shipment_out.packages.new(type=box)
+ >>> moves = package2.moves.find()
+ >>> len(moves)
+ 1
+ >>> package2.moves.append(moves[0])
+
+ >>> shipment_out.click('pack')
diff --git a/modules/stock_package/tests/test_module.py b/modules/stock_package/tests/test_module.py
new file mode 100644
index 0000000000..9cb0598b20
--- /dev/null
+++ b/modules/stock_package/tests/test_module.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockPackageTestCase(ModuleTestCase):
+ 'Test Stock Package module'
+ module = 'stock_package'
+
+
+del ModuleTestCase
diff --git a/modules/stock_package/tests/test_scenario.py b/modules/stock_package/tests/test_scenario.py
new file mode 100644
index 0000000000..dc1d23e7e5
--- /dev/null
+++ b/modules/stock_package/tests/test_scenario.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import load_doc_tests
+
+
+def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_package/tox.ini b/modules/stock_package/tox.ini
new file mode 100644
index 0000000000..ca515eb9f8
--- /dev/null
+++ b/modules/stock_package/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_package/* -m unittest discover -s tests
+ coverage report --include=./**/stock_package/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_package/tryton.cfg b/modules/stock_package/tryton.cfg
new file mode 100644
index 0000000000..0d1929652b
--- /dev/null
+++ b/modules/stock_package/tryton.cfg
@@ -0,0 +1,13 @@
+[tryton]
+version=6.7.0
+depends:
+ company
+ ir
+ product
+ res
+ stock
+extras_depend:
+ carrier_weight
+xml:
+ stock.xml
+ message.xml
diff --git a/modules/stock_package/view/configuration_form.xml b/modules/stock_package/view/configuration_form.xml
new file mode 100644
index 0000000000..ef9f56c1a3
--- /dev/null
+++ b/modules/stock_package/view/configuration_form.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package/view/package_form.xml b/modules/stock_package/view/package_form.xml
new file mode 100644
index 0000000000..f149fc19d9
--- /dev/null
+++ b/modules/stock_package/view/package_form.xml
@@ -0,0 +1,46 @@
+
+
+
diff --git a/modules/stock_package/view/package_list.xml b/modules/stock_package/view/package_list.xml
new file mode 100644
index 0000000000..90fad2532c
--- /dev/null
+++ b/modules/stock_package/view/package_list.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package/view/package_tree.xml b/modules/stock_package/view/package_tree.xml
new file mode 100644
index 0000000000..0d22e557f5
--- /dev/null
+++ b/modules/stock_package/view/package_tree.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package/view/package_type_form.xml b/modules/stock_package/view/package_type_form.xml
new file mode 100644
index 0000000000..4b786518f2
--- /dev/null
+++ b/modules/stock_package/view/package_type_form.xml
@@ -0,0 +1,32 @@
+
+
+
diff --git a/modules/stock_package/view/package_type_list.xml b/modules/stock_package/view/package_type_list.xml
new file mode 100644
index 0000000000..b4d89538b1
--- /dev/null
+++ b/modules/stock_package/view/package_type_list.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/modules/stock_package/view/shipment_in_return_form.xml b/modules/stock_package/view/shipment_in_return_form.xml
new file mode 100644
index 0000000000..20332f6659
--- /dev/null
+++ b/modules/stock_package/view/shipment_in_return_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/modules/stock_package/view/shipment_out_form.xml b/modules/stock_package/view/shipment_out_form.xml
new file mode 100644
index 0000000000..8b2d43a96c
--- /dev/null
+++ b/modules/stock_package/view/shipment_out_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/modules/stock_package/view/stock_move_form.xml b/modules/stock_package/view/stock_move_form.xml
new file mode 100644
index 0000000000..a98335d02b
--- /dev/null
+++ b/modules/stock_package/view/stock_move_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping/.drone.yml b/modules/stock_package_shipping/.drone.yml
new file mode 100644
index 0000000000..b45ef267ef
--- /dev/null
+++ b/modules/stock_package_shipping/.drone.yml
@@ -0,0 +1,78 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+ check_doc:
+ image: ${IMAGE}
+ commands:
+ - pip install sphinx
+ - python -m sphinx -T -E -W -n -b html doc _build/html
+ - python -m sphinx -T -E -W -n -b linkcheck doc _build
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_package_shipping/.flake8 b/modules/stock_package_shipping/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_package_shipping/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_package_shipping/.isort.cfg b/modules/stock_package_shipping/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_package_shipping/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_package_shipping/CHANGELOG b/modules/stock_package_shipping/CHANGELOG
new file mode 100644
index 0000000000..95c820da2b
--- /dev/null
+++ b/modules/stock_package_shipping/CHANGELOG
@@ -0,0 +1,61 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Add wizard to print shipping labels
+
+Version 6.0.0 - 2021-05-03
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Add tracking URL
+* Allow updating dimensions on package
+* Add configuration option to store label in filestore
+* Manage supplier shipment returns
+
+Version 5.8.0 - 2020-11-02
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Move package weight to stock_shipment_measurements module
+
+Version 4.2.0 - 2016-11-28
+--------------------------
+* Initial release
diff --git a/modules/stock_package_shipping/COPYRIGHT b/modules/stock_package_shipping/COPYRIGHT
new file mode 100644
index 0000000000..507bb67d3e
--- /dev/null
+++ b/modules/stock_package_shipping/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2016-2022 Nicolas Évrard.
+Copyright (C) 2016-2022 B2CK.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_package_shipping/LICENSE b/modules/stock_package_shipping/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_package_shipping/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_package_shipping/MANIFEST.in b/modules/stock_package_shipping/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_package_shipping/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_package_shipping/README.rst b/modules/stock_package_shipping/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_package_shipping/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_package_shipping/__init__.py b/modules/stock_package_shipping/__init__.py
new file mode 100644
index 0000000000..93565afe2c
--- /dev/null
+++ b/modules/stock_package_shipping/__init__.py
@@ -0,0 +1,23 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import carrier, stock
+
+
+def register():
+ Pool.register(
+ stock.PackageType,
+ stock.Package,
+ stock.ShipmentOut,
+ stock.ShipmentInReturn,
+ carrier.Carrier,
+ module='stock_package_shipping', type_='model')
+ Pool.register(
+ stock.CreateShipping,
+ stock.PrintShippingLabel,
+ module='stock_package_shipping', type_='wizard')
+ Pool.register(
+ stock.ShippingLabel,
+ module='stock_package_shipping', type_='report')
diff --git a/modules/stock_package_shipping/carrier.py b/modules/stock_package_shipping/carrier.py
new file mode 100644
index 0000000000..7012df7128
--- /dev/null
+++ b/modules/stock_package_shipping/carrier.py
@@ -0,0 +1,17 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.model import fields
+from trytond.pool import PoolMeta
+
+
+class Carrier(metaclass=PoolMeta):
+ __name__ = 'carrier'
+
+ shipping_service = fields.Selection([
+ (None, ''),
+ ], 'Shipping Service')
+
+ @property
+ def shipping_label_mimetype(self):
+ return 'application/octet-stream'
diff --git a/modules/stock_package_shipping/carrier.xml b/modules/stock_package_shipping/carrier.xml
new file mode 100644
index 0000000000..cb69bd1376
--- /dev/null
+++ b/modules/stock_package_shipping/carrier.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+ carrier
+
+ carrier_form
+
+
+ carrier
+
+ carrier_tree
+
+
+
diff --git a/modules/stock_package_shipping/doc/conf.py b/modules/stock_package_shipping/doc/conf.py
new file mode 100644
index 0000000000..8513b72dd2
--- /dev/null
+++ b/modules/stock_package_shipping/doc/conf.py
@@ -0,0 +1,61 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+modules_url = 'https://docs.tryton.org/projects/modules-{module}/en/{series}/'
+trytond_url = 'https://docs.tryton.org/projects/server/en/{series}/'
+
+
+def get_info():
+ import configparser
+ import os
+ import subprocess
+ import sys
+
+ module_dir = os.path.dirname(os.path.dirname(__file__))
+
+ config = configparser.ConfigParser()
+ config.read_file(open(os.path.join(module_dir, 'tryton.cfg')))
+ info = dict(config.items('tryton'))
+
+ result = subprocess.run(
+ [sys.executable, 'setup.py', '--name'],
+ stdout=subprocess.PIPE, check=True, cwd=module_dir)
+ info['name'] = result.stdout.decode('utf-8').strip()
+
+ result = subprocess.run(
+ [sys.executable, 'setup.py', '--version'],
+ stdout=subprocess.PIPE, check=True, cwd=module_dir)
+ version = result.stdout.decode('utf-8').strip()
+ if 'dev' in version:
+ info['series'] = 'latest'
+ else:
+ info['series'] = '.'.join(version.split('.', 2)[:2])
+
+ for key in {'depends', 'extras_depend'}:
+ info[key] = info.get(key, '').strip().splitlines()
+ info['modules'] = set(info['depends'] + info['extras_depend'])
+ info['modules'] -= {'ir', 'res'}
+
+ return info
+
+
+info = get_info()
+
+master_doc = 'index'
+project = info['name']
+release = version = info['series']
+default_role = 'ref'
+highlight_language = 'none'
+extensions = [
+ 'sphinx.ext.intersphinx',
+ ]
+intersphinx_mapping = {
+ 'trytond': (trytond_url.format(series=version), None),
+ }
+intersphinx_mapping.update({
+ m: (modules_url.format(
+ module=m.replace('_', '-'), series=version), None)
+ for m in info['modules']
+ })
+
+del get_info, info, modules_url, trytond_url
diff --git a/modules/stock_package_shipping/doc/configuration.rst b/modules/stock_package_shipping/doc/configuration.rst
new file mode 100644
index 0000000000..97fd2d25ff
--- /dev/null
+++ b/modules/stock_package_shipping/doc/configuration.rst
@@ -0,0 +1,29 @@
+*************
+Configuration
+*************
+
+The *Stock Package Shipping Module* uses some settings from the
+``[stock_package_shipping]`` section of the :doc:`configuration file
+`.
+
+.. _config-stock_package_shipping.filestore:
+
+``filestore``
+=============
+
+This configuration value indicates whether the shipping label should be stored
+in the :py:mod:`trytond:trytond.filestore` (``True``) or the database
+(``False``).
+
+The default value is: ``False``
+
+.. _config-stock_package_shipping.store_prefix:
+
+``store_prefix``
+================
+
+This is the prefix to use with the :py:mod:`trytond:trytond.filestore`.
+This value is only used when the `filestore
+` setting is in use.
+
+The default value is: ``None``
diff --git a/modules/stock_package_shipping/doc/index.rst b/modules/stock_package_shipping/doc/index.rst
new file mode 100644
index 0000000000..a207b008b5
--- /dev/null
+++ b/modules/stock_package_shipping/doc/index.rst
@@ -0,0 +1,60 @@
+Stock Package Shipping Module
+#############################
+
+This module is the base module required to interact with shipping service
+providers.
+
+Carrier
+*******
+
+The Carrier model adds the following field:
+
+- *Shipping Service*: The shipping service of the carrier.
+
+This field is programmatically filled by the modules providing support for
+shipping companies.
+
+Package Type
+************
+
+The Package Type model has been added the following fields:
+
+- *Length*: The length of the packages of this type
+- *Length Unit*: The unit of measure of this length
+- *Length Digits*: The precision of length
+- *Height*: The height of the packages of this type
+- *Height Unit*: The unit of measure of this height
+- *Height Digits*: The precision of height
+- *Width*: The width of the packages of this type
+- *Width Unit*: The unit of measure of this width
+- *Width Digits*: The precision of width
+
+Package
+*******
+
+The Package model has been added the following fields:
+
+- *Shipping Reference*: The shipping reference provided by the shipping service
+- *Shipping Label*: The shipping label provided by the shipping service
+- *Weight*: A function field computing the weight of the package with its
+ content
+
+Shipment Out
+************
+
+The Shipment Out model will check once in the Packed state if the shipment is a
+valid shipment for the shipping service. He does that by calling a method that
+is by convention named ``validate_packing_``.
+
+Once a shipment is packed, the user can create the shipping for each packages
+with the shipping service by clicking on the *Create Shipping* button. This
+button triggers a wizard that is overridden in shipping service specific
+modules. The starting state of the wizard is a ``StateTransition``. Its linked
+method is overridden in shipping service modules in order to communicate with
+the service.
+
+.. toctree::
+ :maxdepth: 2
+
+ configuration
+ releases
diff --git a/modules/stock_package_shipping/doc/releases.rst b/modules/stock_package_shipping/doc/releases.rst
new file mode 100644
index 0000000000..21b13c4745
--- /dev/null
+++ b/modules/stock_package_shipping/doc/releases.rst
@@ -0,0 +1,7 @@
+.. _releases-index:
+
+=============
+Release notes
+=============
+
+.. include:: ../CHANGELOG
diff --git a/modules/stock_package_shipping/exceptions.py b/modules/stock_package_shipping/exceptions.py
new file mode 100644
index 0000000000..dc0bc7edb2
--- /dev/null
+++ b/modules/stock_package_shipping/exceptions.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.exceptions import UserError, UserWarning
+
+
+class PackWarning(UserWarning):
+ pass
+
+
+class PackingValidationError(UserError):
+ pass
diff --git a/modules/stock_package_shipping/locale/bg.po b/modules/stock_package_shipping/locale/bg.po
new file mode 100644
index 0000000000..7191f2b906
--- /dev/null
+++ b/modules/stock_package_shipping/locale/bg.po
@@ -0,0 +1,165 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr "Височина"
+
+#, fuzzy
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr "Цифри за височина"
+
+#, fuzzy
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr "Цифри за височина"
+
+#, fuzzy
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr "Дължина"
+
+#, fuzzy
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr "Цифри за дължина"
+
+#, fuzzy
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr "Цифри за дължина"
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Shipping"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "Ширина"
+
+#, fuzzy
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr "Цифри за ширина"
+
+#, fuzzy
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr "Цифри за ширина"
+
+#, fuzzy
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr "Височина"
+
+#, fuzzy
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr "Цифри за височина"
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr "Дължина"
+
+#, fuzzy
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr "Цифри за дължина"
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "Ширина"
+
+#, fuzzy
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr "Цифри за ширина"
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Create Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Shipping"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
diff --git a/modules/stock_package_shipping/locale/ca.po b/modules/stock_package_shipping/locale/ca.po
new file mode 100644
index 0000000000..390ef2d3ab
--- /dev/null
+++ b/modules/stock_package_shipping/locale/ca.po
@@ -0,0 +1,146 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr "Servei d'enviament"
+
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr "Altura"
+
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr "Decimals de l'altura"
+
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr "Unitat de l'altura"
+
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr "Longitud"
+
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr "Decimals de la longitud"
+
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr "Unitat de la longitud"
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr "Etiqueta d'enviament"
+
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "ID de l'etiqueta d'enviament"
+
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Tipus MIME d'etiqueta d'enviament"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr "Referència d'enviament"
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr "URL de seguiment de l'enviament"
+
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "Amplada"
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr "Decimals de l'amplada"
+
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr "Unitat de l'amplada"
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr "Altura"
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr "Decimals de l'altura"
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr "Unitat de l'altura"
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr "Longitud"
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr "Decimals de la longitud"
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr "Unitat de la longitud"
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "Amplada"
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr "Decimals de l'amplada"
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr "Unitat de l'amplada"
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr "Transportista"
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr "Descripció de l'enviament"
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr "Descripció d'enviament"
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Crea enviament"
+
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Etiqueta d'enviament"
+
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Etiquetes d'enviament"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+"Per crear etiquetes d'enviament per l'albarà \"%(shipment)s\", l'heu "
+"d'empaquetar."
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr "L'albarà \"%(shipment)s\" no té assignat un transportista."
+
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Etiqueta d'enviament"
+
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Crea enviament per paquets"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Crea enviament per paquets"
diff --git a/modules/stock_package_shipping/locale/cs.po b/modules/stock_package_shipping/locale/cs.po
new file mode 100644
index 0000000000..02461bcfeb
--- /dev/null
+++ b/modules/stock_package_shipping/locale/cs.po
@@ -0,0 +1,150 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr ""
+
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Shipping"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Create Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Shipping"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
diff --git a/modules/stock_package_shipping/locale/de.po b/modules/stock_package_shipping/locale/de.po
new file mode 100644
index 0000000000..e8ec0533ef
--- /dev/null
+++ b/modules/stock_package_shipping/locale/de.po
@@ -0,0 +1,146 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr "Versanddienst"
+
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr "Höhe"
+
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr "Nachkommastellen Höhe"
+
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr "Einheit Höhe"
+
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr "Länge"
+
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr "Nachkommastellen Länge"
+
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr "Einheit Länge"
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr "Versandetikett"
+
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "ID Versandetikett"
+
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "MIME-Typ Versandetikett"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr "Versandbeleg"
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr "Versand Tracking URL"
+
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "Breite"
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr "Nachkommastellen Breite"
+
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr "Einheit Breite"
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr "Höhe"
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr "Nachkommastellen Höhe"
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr "Einheit Höhe"
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr "Länge"
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr "Nachkommastellen Länge"
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr "Einheit Länge"
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "Breite"
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr "Nachkommastellen Breite"
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr "Einheit Breite"
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr "Versanddienstleister"
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr "Versandbeschreibung"
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr "Versandbeschreibung"
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Versand erstellen"
+
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Versandetikett"
+
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Versandetiketten"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+"Damit die Versandaufkleber für die Lieferung \"%(shipment)s\" generiert "
+"werden können, muss die Lieferung zuerst gepackt werden."
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr "Der Lieferung \"%(shipment)s\" ist kein Versanddienstleister zugeordnet."
+
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Versandetikett"
+
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Versand für Pakete erstellen"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Versand erstellen"
diff --git a/modules/stock_package_shipping/locale/es.po b/modules/stock_package_shipping/locale/es.po
new file mode 100644
index 0000000000..b8fb874106
--- /dev/null
+++ b/modules/stock_package_shipping/locale/es.po
@@ -0,0 +1,146 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr "Servicio de envío"
+
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr "Altura"
+
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr "Decimales de la altura"
+
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr "Unidad de la altura"
+
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr "Longitud"
+
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr "Decimales de la longitud"
+
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr "Unidad de la longitud"
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr "Etiqueta de envío"
+
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "ID de la etiqueta de envío"
+
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Tipo MIME de la etiqueta de envío"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr "Referencia de envío"
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr "URL Seguimiento del envío"
+
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "Ancho"
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr "Decimales del ancho"
+
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr "Unidad del ancho"
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr "Altura"
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr "Decimales de la altura"
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr "Unidad de la altura"
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr "Longitud"
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr "Decimales de la longitud"
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr "Unidad de la longitud"
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "Ancho"
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr "Decimales del ancho"
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr "Unidad del ancho"
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr "Transportista"
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr "Descripción del envío"
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr "Descripción del envío"
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Crear envío"
+
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Etiqueta de envío"
+
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Etiquetas de envío"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+"Para crear etiquetas de envío para el albarán \"%(shipment)s\", debe "
+"empaquetar-lo."
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr "El albarán \"%(shipment)s\" no tiene asignado ningún transportista."
+
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Etiqueta de envío"
+
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Crear envío para paquetes"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Crear envío de paquetes"
diff --git a/modules/stock_package_shipping/locale/es_419.po b/modules/stock_package_shipping/locale/es_419.po
new file mode 100644
index 0000000000..7c27edfcca
--- /dev/null
+++ b/modules/stock_package_shipping/locale/es_419.po
@@ -0,0 +1,145 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr ""
+
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr ""
+
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr "El envío \"%(shipment)s\" no tiene asignado ningún transportista."
+
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr ""
diff --git a/modules/stock_package_shipping/locale/et.po b/modules/stock_package_shipping/locale/et.po
new file mode 100644
index 0000000000..1d117906f1
--- /dev/null
+++ b/modules/stock_package_shipping/locale/et.po
@@ -0,0 +1,160 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr "Tarne teenus"
+
+#, fuzzy
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr "Kõrgus"
+
+#, fuzzy
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr "Kõrguse numbriväärtus"
+
+#, fuzzy
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr "Kõrguse ühik"
+
+#, fuzzy
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr "Pikkus"
+
+#, fuzzy
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr "Pikkuse numbriväärtus"
+
+#, fuzzy
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr "Pikkuse ühik"
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr "Lähetuse etikett"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "Lähetuse etikett"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Lähetuse etikett"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr "Lähetuse viide"
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "Laius"
+
+#, fuzzy
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr "Laiuse numbriväärtus"
+
+#, fuzzy
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr "Laiuse ühik"
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr "Kõrgus"
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr "Kõrguse numbriväärtus"
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr "Kõrguse ühik"
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr "Pikkus"
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr "Pikkuse numbriväärtus"
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr "Pikkuse ühik"
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "Laius"
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr "Laiuse numbriväärtus"
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr "Laiuse ühik"
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr "Lähetuse kirjeldus"
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr "Lähetuse kirjeldus"
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Loo lähetus"
+
+#, fuzzy
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Lähetuse etikett"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Lähetuse etikett"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr "Lähetuse \"%(shipment)s\" etikettide loomiseks tuleb see pakkida."
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr "Lähetusel \"%(shipment)s\" ei ole vedajat."
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Lähetuse etikett"
+
+#, fuzzy
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Loo saadetistele lähetus"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Loo saadetistele lähetus"
diff --git a/modules/stock_package_shipping/locale/fa.po b/modules/stock_package_shipping/locale/fa.po
new file mode 100644
index 0000000000..cab38a1d92
--- /dev/null
+++ b/modules/stock_package_shipping/locale/fa.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr "خدمات حمل ونقل"
+
+#, fuzzy
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr "ارتفاع"
+
+#, fuzzy
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr "ارقام ارتفاع"
+
+#, fuzzy
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr "واحد ارتفاع"
+
+#, fuzzy
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr "طول"
+
+#, fuzzy
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr "ارقام طول"
+
+#, fuzzy
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr "واحد طول"
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr "برچسب حمل ونقل"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "برچسب حمل ونقل"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "برچسب حمل ونقل"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr "مرجع حمل ونقل"
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "عرض"
+
+#, fuzzy
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr "ارقام عرض"
+
+#, fuzzy
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr "واحد عرض"
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr "ارتفاع"
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr "ارقام ارتفاع"
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr "واحد ارتفاع"
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr "طول"
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr "ارقام طول"
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr "واحد طول"
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "عرض"
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr "ارقام عرض"
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr "واحد عرض"
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr "شرح حمل ونقل"
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr "شرح حمل ونقل"
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "ایجاد حمل ونقل"
+
+#, fuzzy
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "برچسب حمل ونقل"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "برچسب حمل ونقل"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+"برای ایجاد برچسب های حمل و نقل محموله :\"%(shipment)s\"، شما باید آن را بسته"
+" بندی کنید."
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr "هیچ حمل کننده ایی برای محموله : \"%s\" تنظیم نشده است."
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "برچسب حمل ونقل"
+
+#, fuzzy
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
diff --git a/modules/stock_package_shipping/locale/fi.po b/modules/stock_package_shipping/locale/fi.po
new file mode 100644
index 0000000000..02461bcfeb
--- /dev/null
+++ b/modules/stock_package_shipping/locale/fi.po
@@ -0,0 +1,150 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr ""
+
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Shipping"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Create Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Shipping"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
diff --git a/modules/stock_package_shipping/locale/fr.po b/modules/stock_package_shipping/locale/fr.po
new file mode 100644
index 0000000000..b5ebcce625
--- /dev/null
+++ b/modules/stock_package_shipping/locale/fr.po
@@ -0,0 +1,146 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr "Service de livraison"
+
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr "Hauteur"
+
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr "Décimales de la hauteur"
+
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr "Unité de hauteur"
+
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr "Longueur"
+
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr "Décimales de la longueur"
+
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr "Unité de longueur"
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr "Étiquette de livraison"
+
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "ID de l'étiquette de livraison"
+
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Type MIME d'étiquette d'expédition"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr "Référence de livraison"
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr "URL de suivi des envois"
+
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "Largeur"
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr "Décimales de la largeur"
+
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr "Unité de largeur"
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr "Hauteur"
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr "Décimales de la hauteur"
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr "Unité de hauteur"
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr "Longueur"
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr "Décimales de la longueur"
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr "Unité de longueur"
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "Largeur"
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr "Décimales de la largeur"
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr "Unité de largeur"
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr "Transporteur"
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr "Description de la livraison"
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr "Description de la livraison"
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Créer la livraison"
+
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Étiquette de livraison"
+
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Étiquettes de livraison"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+"Pour créer les étiquettes de livraison pour l'expédition « %(shipment)s », "
+"vous devez l'emballer."
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr "L'expédition « %(shipment)s » n'a pas de transporteur défini."
+
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Étiquette de livraison"
+
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Créer la livraison pour les emballages"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Créer la livraison pour les emballages"
diff --git a/modules/stock_package_shipping/locale/hu.po b/modules/stock_package_shipping/locale/hu.po
new file mode 100644
index 0000000000..dedbc90388
--- /dev/null
+++ b/modules/stock_package_shipping/locale/hu.po
@@ -0,0 +1,165 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr "Magasság"
+
+#, fuzzy
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr "Vessző utáni magasság"
+
+#, fuzzy
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr "Vessző utáni magasság"
+
+#, fuzzy
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr "Hossz"
+
+#, fuzzy
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr "Vessző utáni hossz"
+
+#, fuzzy
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr "Vessző utáni hossz"
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Shipping"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "Szélesség"
+
+#, fuzzy
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr "Vessző utáni tömeg"
+
+#, fuzzy
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr "Vessző utáni tömeg"
+
+#, fuzzy
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr "Magasság"
+
+#, fuzzy
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr "Vessző utáni magasság"
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr "Hossz"
+
+#, fuzzy
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr "Vessző utáni hossz"
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "Szélesség"
+
+#, fuzzy
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr "Vessző utáni tömeg"
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Create Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Shipping"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
diff --git a/modules/stock_package_shipping/locale/id.po b/modules/stock_package_shipping/locale/id.po
new file mode 100644
index 0000000000..e84f76cbca
--- /dev/null
+++ b/modules/stock_package_shipping/locale/id.po
@@ -0,0 +1,144 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr ""
+
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr "Tinggi"
+
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr "Panjang"
+
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "Lebar"
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr "Tinggi"
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr "Panjang"
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "Lebar"
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr ""
+
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr ""
diff --git a/modules/stock_package_shipping/locale/it.po b/modules/stock_package_shipping/locale/it.po
new file mode 100644
index 0000000000..2f705c4056
--- /dev/null
+++ b/modules/stock_package_shipping/locale/it.po
@@ -0,0 +1,153 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr ""
+
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Shipping"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "Larghezza"
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr "Larghezza"
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "Larghezza"
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr "Vettore"
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Create Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Shipping"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
diff --git a/modules/stock_package_shipping/locale/lo.po b/modules/stock_package_shipping/locale/lo.po
new file mode 100644
index 0000000000..a52c7fcf33
--- /dev/null
+++ b/modules/stock_package_shipping/locale/lo.po
@@ -0,0 +1,158 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr "ນໍ້າໜັກ"
+
+#, fuzzy
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr "ນໍ້າໜັກ"
+
+#, fuzzy
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr "ນໍ້າໜັກ"
+
+#, fuzzy
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr "ຄວາມຍາວ"
+
+#, fuzzy
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr "ຄວາມຍາວ"
+
+#, fuzzy
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr "ຄວາມຍາວ"
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Shipping"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr "ນໍ້າໜັກ"
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr "ຄວາມຍາວ"
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Create Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Shipping"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
diff --git a/modules/stock_package_shipping/locale/lt.po b/modules/stock_package_shipping/locale/lt.po
new file mode 100644
index 0000000000..02461bcfeb
--- /dev/null
+++ b/modules/stock_package_shipping/locale/lt.po
@@ -0,0 +1,150 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr ""
+
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Shipping"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Create Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Shipping"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
diff --git a/modules/stock_package_shipping/locale/nl.po b/modules/stock_package_shipping/locale/nl.po
new file mode 100644
index 0000000000..4504930b34
--- /dev/null
+++ b/modules/stock_package_shipping/locale/nl.po
@@ -0,0 +1,146 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr "Verzendservice"
+
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr "Hoogte"
+
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr "Hoogte decimalen"
+
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr "Hoogte eenheid"
+
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr "Lengte"
+
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr "Lengte decimalen"
+
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr "Lengte-eenheid"
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr "Verzendlabel"
+
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "Verzendlabel-ID"
+
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Verzendlabel MIME-type"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr "Verzendreferentie"
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr "Tracking-URL verzending"
+
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "Breedte"
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr "Decimalen breedte"
+
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr "Breedte eenheid"
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr "Hoogte"
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr "Hoogte decimalen"
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr "Hoogte eenheid"
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr "Lengte"
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr "Lengte decimalen"
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr "Lengte-eenheid"
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "Breedte"
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr "Decimalen breedte"
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr "Breedte eenheid"
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr "Transporteur"
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr "Verzending omschrijving"
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr "Verzending omschrijving"
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Maak zending"
+
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Verzendlabel"
+
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Verzendlabels"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+"Om verzendlabels te maken voor verzending \"%(shipment)s\", moet u deze "
+"verpakken."
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr "De zending \"%(shipment)s\" heeft geen transporteur."
+
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Verzendlabel"
+
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Maak een verzending voor de pakketten"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Maak een verzending voor de pakketten"
diff --git a/modules/stock_package_shipping/locale/pl.po b/modules/stock_package_shipping/locale/pl.po
new file mode 100644
index 0000000000..c777ad8924
--- /dev/null
+++ b/modules/stock_package_shipping/locale/pl.po
@@ -0,0 +1,159 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr "Wysokość"
+
+#, fuzzy
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr "Cyfry wysokości"
+
+#, fuzzy
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr "Jednostka wysokości"
+
+#, fuzzy
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr "Długość"
+
+#, fuzzy
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr "Cyfry długości"
+
+#, fuzzy
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr "Jednostka długości"
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Shipping"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "Szerokość"
+
+#, fuzzy
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr "Cyfry szerokości"
+
+#, fuzzy
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr "Jednostka szerokości"
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr "Wysokość"
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr "Cyfry wysokości"
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr "Jednostka wysokości"
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr "Długość"
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr "Cyfry długości"
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr "Jednostka długości"
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "Szerokość"
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr "Cyfry szerokości"
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr "Jednostka szerokości"
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Create Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Shipping"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
diff --git a/modules/stock_package_shipping/locale/pt.po b/modules/stock_package_shipping/locale/pt.po
new file mode 100644
index 0000000000..8bdb5cdb36
--- /dev/null
+++ b/modules/stock_package_shipping/locale/pt.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr "Serviço de Envio"
+
+#, fuzzy
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr "Altura"
+
+#, fuzzy
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr "Dígitos decimais da altura"
+
+#, fuzzy
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr "Unidade da Altura"
+
+#, fuzzy
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr "Comprimento"
+
+#, fuzzy
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr "Dígitos decimais do comprimento"
+
+#, fuzzy
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr "Unidade do Comprimento"
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr "Etiquetas de envio"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "Etiquetas de envio"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Etiquetas de envio"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr "Referência de Envio"
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "Largura"
+
+#, fuzzy
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr "Dígitos decimais da largura"
+
+#, fuzzy
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr "Unidade da Largura"
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr "Altura"
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr "Dígitos decimais da altura"
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr "Unidade da Altura"
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr "Comprimento"
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr "Dígitos decimais do comprimento"
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr "Unidade do Comprimento"
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "Largura"
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr "Dígitos decimais da largura"
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr "Unidade da Largura"
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr "Descrição do Envio"
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr "Descrição do Envio"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Create Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Etiquetas de envio"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Etiquetas de envio"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr "A remessa \"%(shipment)s\" não tem uma transportadora definida."
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Etiquetas de envio"
+
+#, fuzzy
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
diff --git a/modules/stock_package_shipping/locale/ro.po b/modules/stock_package_shipping/locale/ro.po
new file mode 100644
index 0000000000..b3090e6bd5
--- /dev/null
+++ b/modules/stock_package_shipping/locale/ro.po
@@ -0,0 +1,144 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr ""
+
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr ""
+
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr ""
diff --git a/modules/stock_package_shipping/locale/ru.po b/modules/stock_package_shipping/locale/ru.po
new file mode 100644
index 0000000000..624751c956
--- /dev/null
+++ b/modules/stock_package_shipping/locale/ru.po
@@ -0,0 +1,161 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr "Ширина"
+
+#, fuzzy
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr "Ширина"
+
+#, fuzzy
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr "Ширина"
+
+#, fuzzy
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr "Длина"
+
+#, fuzzy
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr "Длина"
+
+#, fuzzy
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr "Длина"
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Shipping"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "Ширина"
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr "Ширина"
+
+#, fuzzy
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr "Ширина"
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr "Длина"
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "Ширина"
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Create Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Shipping"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
diff --git a/modules/stock_package_shipping/locale/sl.po b/modules/stock_package_shipping/locale/sl.po
new file mode 100644
index 0000000000..95533a6af8
--- /dev/null
+++ b/modules/stock_package_shipping/locale/sl.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr "Dostavna služba"
+
+#, fuzzy
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr "Višina"
+
+#, fuzzy
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr "Decimalke za višino"
+
+#, fuzzy
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr "Enota višine"
+
+#, fuzzy
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr "Dolžina"
+
+#, fuzzy
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr "Decimalke za dolžino"
+
+#, fuzzy
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr "Enota dolžine"
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr "Nalepka pošiljke"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "Nalepka pošiljke"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Nalepka pošiljke"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr "Sklic paketne dostave"
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "Širina"
+
+#, fuzzy
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr "Decimalke za širino"
+
+#, fuzzy
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr "Enota širine"
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr "Višina"
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr "Decimalke za višino"
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr "Enota višine"
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr "Dolžina"
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr "Decimalke za dolžino"
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr "Enota dolžine"
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "Širina"
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr "Decimalke za širino"
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr "Enota širine"
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr "Opis pošiljke"
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr "Opis pošiljke"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Create Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Nalepka pošiljke"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Nalepka pošiljke"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr "Za dostavo \"%(shipment)s\" še ni izbran špediter."
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Nalepka pošiljke"
+
+#, fuzzy
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
diff --git a/modules/stock_package_shipping/locale/tr.po b/modules/stock_package_shipping/locale/tr.po
new file mode 100644
index 0000000000..02461bcfeb
--- /dev/null
+++ b/modules/stock_package_shipping/locale/tr.po
@@ -0,0 +1,150 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr ""
+
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Shipping"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Create Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Shipping"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
diff --git a/modules/stock_package_shipping/locale/uk.po b/modules/stock_package_shipping/locale/uk.po
new file mode 100644
index 0000000000..b3090e6bd5
--- /dev/null
+++ b/modules/stock_package_shipping/locale/uk.po
@@ -0,0 +1,144 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr ""
+
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr ""
+
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr ""
+
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr ""
diff --git a/modules/stock_package_shipping/locale/zh_CN.po b/modules/stock_package_shipping/locale/zh_CN.po
new file mode 100644
index 0000000000..1144f0af04
--- /dev/null
+++ b/modules/stock_package_shipping/locale/zh_CN.po
@@ -0,0 +1,153 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipping_service:"
+msgid "Shipping Service"
+msgstr ""
+
+msgctxt "field:stock.package,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_label:"
+msgid "Shipping Label"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_id:"
+msgid "Shipping Label ID"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "field:stock.package,shipping_label_mimetype:"
+msgid "Shipping Label MIME Type"
+msgstr "Shipping"
+
+msgctxt "field:stock.package,shipping_reference:"
+msgid "Shipping Reference"
+msgstr ""
+
+msgctxt "field:stock.package,shipping_tracking_url:"
+msgid "Shipping Tracking URL"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,width:"
+msgid "Width"
+msgstr "宽"
+
+msgctxt "field:stock.package,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package,width_uom:"
+msgid "Width Unit"
+msgstr "宽"
+
+msgctxt "field:stock.package.type,height:"
+msgid "Height"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_digits:"
+msgid "Height Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,height_uom:"
+msgid "Height Unit"
+msgstr ""
+
+msgctxt "field:stock.package.type,length:"
+msgid "Length"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_digits:"
+msgid "Length Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,length_uom:"
+msgid "Length Unit"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.package.type,width:"
+msgid "Width"
+msgstr "宽"
+
+msgctxt "field:stock.package.type,width_digits:"
+msgid "Width Digits"
+msgstr ""
+
+msgctxt "field:stock.package.type,width_uom:"
+msgid "Width Unit"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipping_description:"
+msgid "Shipping Description"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Shipping"
+msgstr "Create Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:report_shipping_label"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_print_shipping_label"
+msgid "Shipping Labels"
+msgstr "Shipping"
+
+msgctxt "model:ir.message,text:msg_shipment_not_packed"
+msgid "To create shipping labels for shipment \"%(shipment)s\", you must pack it."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_without_carrier"
+msgid "The shipment \"%(shipment)s\" does not have a carrier set."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.model.button,string:package_print_shipping_label_button"
+msgid "Shipping Label"
+msgstr "Shipping"
+
+#, fuzzy
+msgctxt ""
+"model:ir.model.button,string:shipment_in_return_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
+
+msgctxt "model:ir.model.button,string:shipment_out_create_shipping_button"
+msgid "Create Shipping for Packages"
+msgstr "Create Shipping for Packages"
diff --git a/modules/stock_package_shipping/message.xml b/modules/stock_package_shipping/message.xml
new file mode 100644
index 0000000000..f9624b8804
--- /dev/null
+++ b/modules/stock_package_shipping/message.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+ To create shipping labels for shipment "%(shipment)s", you must pack it.
+
+
+ The shipment "%(shipment)s" does not have a carrier set.
+
+
+
diff --git a/modules/stock_package_shipping/setup.py b/modules/stock_package_shipping/setup.py
new file mode 100755
index 0000000000..bd0037bdf3
--- /dev/null
+++ b/modules/stock_package_shipping/setup.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ content = io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+ content = re.sub(
+ r'(?m)^\.\. toctree::\r?\n((^$|^\s.*$)\r?\n)*', '', content)
+ return content
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_package_shipping'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = ['python-sql >= 0.4']
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [get_require_version('proteus')]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description=('The package shipping module of the '
+ 'Tryton application platform.'),
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_package_shipping',
+ },
+ keywords='tryton stock package shipping',
+ package_dir={'trytond.modules.stock_package_shipping': '.'},
+ packages=(
+ ['trytond.modules.stock_package_shipping']
+ + ['trytond.modules.stock_package_shipping.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_package_shipping': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_package_shipping = trytond.modules.stock_package_shipping
+ """,
+ )
diff --git a/modules/stock_package_shipping/stock.py b/modules/stock_package_shipping/stock.py
new file mode 100644
index 0000000000..01a5f1264c
--- /dev/null
+++ b/modules/stock_package_shipping/stock.py
@@ -0,0 +1,399 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import mimetypes
+
+from sql import Column
+
+from trytond.config import config
+from trytond.i18n import gettext
+from trytond.model import ModelView, Workflow, fields
+from trytond.model.exceptions import AccessError
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Bool, Eval, Id
+from trytond.report import Report
+from trytond.transaction import Transaction
+from trytond.wizard import StateAction, StateTransition, Wizard
+
+from .exceptions import PackWarning
+
+if config.getboolean('stock_package_shipping', 'filestore', default=False):
+ file_id = 'shipping_label_id'
+ store_prefix = config.get(
+ 'stock_package_shipping', 'store_prefix', default=None)
+else:
+ file_id = store_prefix = None
+
+
+class DimensionsMixin(object):
+ __slots__ = ()
+
+ length = fields.Float('Length', digits=(16, Eval('length_digits', 2)))
+ length_uom = fields.Many2One('product.uom', 'Length Unit',
+ domain=[
+ ('category', '=', Id('product', 'uom_cat_length')),
+ ],
+ states={
+ 'required': Bool(Eval('length')),
+ },
+ depends={'length_digits'})
+ length_digits = fields.Function(fields.Integer('Length Digits'),
+ 'on_change_with_length_digits')
+ height = fields.Float('Height', digits=(16, Eval('height_digits', 2)))
+ height_uom = fields.Many2One('product.uom', 'Height Unit',
+ domain=[
+ ('category', '=', Id('product', 'uom_cat_length')),
+ ],
+ states={
+ 'required': Bool(Eval('height')),
+ },
+ depends={'height_digits'})
+ height_digits = fields.Function(fields.Integer('Height Digits'),
+ 'on_change_with_height_digits')
+ width = fields.Float('Width', digits=(16, Eval('width_digits', 2)))
+ width_uom = fields.Many2One('product.uom', 'Width Unit',
+ domain=[
+ ('category', '=', Id('product', 'uom_cat_length')),
+ ],
+ states={
+ 'required': Bool(Eval('width')),
+ },
+ depends={'width_digits'})
+ width_digits = fields.Function(fields.Integer('Width Digits'),
+ 'on_change_with_width_digits')
+
+ @fields.depends('length_uom')
+ def on_change_with_length_digits(self, name=None):
+ return (self.length_uom.digits if self.length_uom
+ else self.default_length_digits())
+
+ @fields.depends('height_uom')
+ def on_change_with_height_digits(self, name=None):
+ return (self.height_uom.digits if self.height_uom
+ else self.default_height_digits())
+
+ @fields.depends('width_uom')
+ def on_change_with_width_digits(self, name=None):
+ return (self.width_uom.digits if self.width_uom
+ else self.default_width_digits())
+
+ @classmethod
+ def default_length_digits(cls):
+ return 2
+
+ @classmethod
+ def default_height_digits(cls):
+ return 2
+
+ @classmethod
+ def default_width_digits(cls):
+ return 2
+
+
+class PackageType(DimensionsMixin, metaclass=PoolMeta):
+ __name__ = 'stock.package.type'
+
+
+class Package(DimensionsMixin, metaclass=PoolMeta):
+ __name__ = 'stock.package'
+
+ shipping_reference = fields.Char('Shipping Reference',
+ states={
+ 'readonly': Eval('_parent_shipment', {}).get('carrier', False),
+ })
+ shipping_label = fields.Binary(
+ "Shipping Label", readonly=True,
+ file_id=file_id, store_prefix=store_prefix)
+ shipping_label_id = fields.Char(
+ "Shipping Label ID", readonly=True, strip=False)
+ shipping_label_mimetype = fields.Char(
+ "Shipping Label MIME Type", readonly=True)
+ shipping_tracking_url = fields.Function(
+ fields.Char(
+ "Shipping Tracking URL",
+ states={
+ 'invisible': ~Eval('shipping_tracking_url'),
+ }),
+ 'get_shipping_tracking_url')
+
+ def get_shipping_tracking_url(self, name):
+ return
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls._buttons.update(
+ print_shipping_label={
+ 'invisible': ~Eval('shipping_label'),
+ 'depends': ['shipping_label'],
+ })
+
+ @classmethod
+ def __register__(cls, module_name):
+ pool = Pool()
+ PackageType = pool.get('stock.package.type')
+ cursor = Transaction().connection.cursor()
+ table = cls.__table__()
+ package_type = PackageType.__table__()
+ table_h = cls.__table_handler__(module_name)
+ dimension_columns = [
+ 'length', 'length_uom',
+ 'height', 'height_uom',
+ 'width', 'width_uom']
+ dimension_exists = any(
+ table_h.column_exist(c) for c in dimension_columns)
+
+ super().__register__(module_name)
+
+ # Migration from 5.8: Update dimensions on package from package_type
+ if not dimension_exists:
+ columns = []
+ values = []
+ for c in dimension_columns:
+ columns.append(Column(table, c))
+ values.append(package_type.select(
+ Column(package_type, c),
+ where=package_type.id == table.type))
+ cursor.execute(*table.update(
+ columns=columns,
+ values=values))
+
+ @classmethod
+ def search_rec_name(cls, name, clause):
+ domain = super(Package, cls).search_rec_name(name, clause)
+ return ['OR', domain,
+ ('shipping_reference',) + tuple(clause[1:]),
+ ]
+
+ @fields.depends('type')
+ def on_change_type(self):
+ super().on_change_type()
+ if self.type:
+ self.length = self.type.length
+ self.length_uom = self.type.length_uom
+ self.height = self.type.height
+ self.height_uom = self.type.height_uom
+ self.width = self.type.width
+ self.width_uom = self.type.width_uom
+
+ @classmethod
+ def copy(cls, packages, default=None):
+ if default is None:
+ default = {}
+ else:
+ default = default.copy()
+ default.setdefault('shipping_reference', None)
+ default.setdefault('shipping_label', None)
+ return super(Package, cls).copy(packages, default=default)
+
+ @classmethod
+ @ModelView.button_action('stock_package_shipping.report_shipping_label')
+ def print_shipping_label(cls, packages):
+ pass
+
+
+class ShippingMixin:
+ __slots__ = ()
+ shipping_description = fields.Char('Shipping Description',
+ states={
+ 'readonly': Eval('state').in_(['done', 'packed'])
+ })
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls._buttons.update({
+ 'create_shipping': {
+ 'invisible': (Eval('reference', False)
+ | ~Eval('carrier', False)),
+ 'readonly': (Eval('reference', False)
+ | ~Eval('root_packages', False)
+ | ~Eval('carrier', False)
+ | ~Eval('state').in_(['packed', 'done'])),
+ 'depends': ['state', 'carrier', 'reference',
+ 'root_packages'],
+ },
+ })
+
+ @classmethod
+ def search_rec_name(cls, name, clause):
+ domain = super().search_rec_name(name, clause)
+ return ['OR', domain,
+ ('reference',) + tuple(clause[1:]),
+ ]
+
+ @classmethod
+ def validate(cls, shipments):
+ super().validate(shipments)
+ for shipment in shipments:
+ if shipment.carrier and shipment.carrier.shipping_service:
+ method_name = ('validate_packing_%s'
+ % shipment.carrier.shipping_service)
+ validator = getattr(shipment, method_name)
+ validator()
+
+ @classmethod
+ def check_no_carrier(cls, shipments):
+ pool = Pool()
+ Warning = pool.get('res.user.warning')
+ for shipment in shipments:
+ if (not shipment.carrier
+ and shipment.delivery_address
+ and shipment.warehouse not in
+ shipment.delivery_address.warehouses):
+ name = 'shipment_out_no_carrier_%s' % shipment
+ if Warning.check(name):
+ raise PackWarning(name,
+ gettext('stock_package_shipping'
+ '.msg_shipment_without_carrier',
+ shipment=shipment.rec_name))
+
+ @classmethod
+ @ModelView.button_action(
+ 'stock_package_shipping.act_create_shipping_wizard')
+ def create_shipping(cls, shipments):
+ for shipment in shipments:
+ if shipment.state not in shipment.shipping_allowed:
+ raise AccessError(
+ gettext('stock_package_shipping.msg_shipment_not_packed',
+ shipment=shipment.rec_name))
+
+ @property
+ def shipping_allowed(self):
+ raise NotImplementedError
+
+ @property
+ def shipping_warehouse(self):
+ raise NotImplementedError
+
+ @property
+ def shipping_to(self):
+ raise NotImplementedError
+
+ @property
+ def shipping_to_address(self):
+ raise NotImplementedError
+
+
+class ShipmentOut(ShippingMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out'
+
+ @classmethod
+ def __register__(cls, module):
+ pool = Pool()
+ ModelData = pool.get('ir.model.data')
+ model_data = ModelData.__table__()
+ cursor = Transaction().connection.cursor()
+ super(ShipmentOut, cls).__register__(module)
+
+ # Migration from 4.6: rename create_shipping xml id
+ if module == 'stock_package_shipping':
+ cursor.execute(*model_data.update(
+ [model_data.fs_id],
+ ['shipment_out_create_shipping_button'],
+ where=(model_data.module == module)
+ & (model_data.model == 'ir.model.button')
+ & (model_data.fs_id == 'create_shipping_button')))
+
+ @classmethod
+ @Workflow.transition('packed')
+ def pack(cls, shipments):
+ super().pack(shipments)
+ cls.check_no_carrier(shipments)
+
+ @property
+ def shipping_allowed(self):
+ return {'packed', 'done'}
+
+ @property
+ def shipping_warehouse(self):
+ return self.warehouse
+
+ @property
+ def shipping_to(self):
+ return self.customer
+
+ @property
+ def shipping_to_address(self):
+ return self.delivery_address
+
+
+class ShipmentInReturn(ShippingMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in.return'
+
+ carrier = fields.Many2One(
+ 'carrier', "Carrier",
+ states={
+ 'readonly': ~Eval('state').in_(['draft', 'waiting', 'assigned']),
+ })
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('done')
+ def done(cls, shipments):
+ super().done(shipments)
+ cls.check_no_carrier(shipments)
+
+ @property
+ def shipping_allowed(self):
+ return {'assigned', 'done'}
+
+ @property
+ def shipping_warehouse(self):
+ return self.from_location.warehouse
+
+ @property
+ def shipping_to(self):
+ return self.supplier
+
+ @property
+ def shipping_to_address(self):
+ return self.delivery_address
+
+
+class CreateShipping(Wizard):
+ 'Create Shipping'
+ __name__ = 'stock.shipment.create_shipping'
+
+ start = StateTransition()
+
+ def transition_start(self):
+ shipping_service = self.record.carrier.shipping_service
+ method_name = 'validate_packing_%s' % shipping_service
+ getattr(self.record, method_name)()
+ return 'end'
+
+
+class ShippingLabel(Report):
+ __name__ = 'stock.package.shipping_label'
+
+ @classmethod
+ def render(cls, report, report_context):
+ package = report_context['record']
+ if not package:
+ return '.bin', b''
+ extension = mimetypes.guess_extension(
+ package.shipping_label_mimetype or 'application/octet-stream')
+ # Return with extension so convert has it
+ return extension, package.shipping_label or b''
+
+ @classmethod
+ def convert(cls, report, data, **kwargs):
+ return data
+
+
+class PrintShippingLabel(Wizard):
+ "Print Shipping Label"
+ __name__ = 'stock.shipment.print_shipping_label'
+ start_state = 'print_'
+ print_ = StateAction('stock_package_shipping.report_shipping_label')
+
+ def do_print_(self, action):
+ package_ids = []
+ labels = set()
+ for shipment in self.records:
+ for package in shipment.packages:
+ if (package.shipping_label
+ and package.shipping_label not in labels):
+ package_ids.append(package.id)
+ labels.add(package.shipping_label)
+ return action, {'ids': package_ids}
diff --git a/modules/stock_package_shipping/stock.xml b/modules/stock_package_shipping/stock.xml
new file mode 100644
index 0000000000..812926116c
--- /dev/null
+++ b/modules/stock_package_shipping/stock.xml
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+ stock.package.type
+
+ package_type_form
+
+
+
+ stock.package
+
+ package_form
+
+
+ stock.package
+
+ package_list
+
+
+
+ print_shipping_label
+ Shipping Label
+
+
+
+
+ stock.shipment.out
+
+ shipment_out_form
+
+
+
+ create_shipping
+ Create Shipping for Packages
+
+
+
+
+ stock.shipment.in.return
+
+ shipment_in_return_form
+
+
+
+ create_shipping
+ Create Shipping for Packages
+
+
+
+
+ Create Shipping
+ stock.shipment.create_shipping
+
+
+
+ Shipping Label
+ stock.package
+ stock.package.shipping_label
+
+ txt
+
+
+ form_print
+ stock.package,-1
+
+
+
+
+ Shipping Labels
+ stock.shipment.print_shipping_label
+
+
+ form_print
+ stock.shipment.out,-1
+
+
+
+ form_print
+ stock.shipment.in.return,-1
+
+
+
+
diff --git a/modules/stock_package_shipping/tests/__init__.py b/modules/stock_package_shipping/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_package_shipping/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_package_shipping/tests/test_module.py b/modules/stock_package_shipping/tests/test_module.py
new file mode 100644
index 0000000000..b630aa1da0
--- /dev/null
+++ b/modules/stock_package_shipping/tests/test_module.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockPackageShippingTestCase(ModuleTestCase):
+ 'Test Stock Package Shipping module'
+ module = 'stock_package_shipping'
+
+
+del ModuleTestCase
diff --git a/modules/stock_package_shipping/tox.ini b/modules/stock_package_shipping/tox.ini
new file mode 100644
index 0000000000..62db059a5c
--- /dev/null
+++ b/modules/stock_package_shipping/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_package_shipping/* -m unittest discover -s tests
+ coverage report --include=./**/stock_package_shipping/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_package_shipping/tryton.cfg b/modules/stock_package_shipping/tryton.cfg
new file mode 100644
index 0000000000..fa8c1f85dc
--- /dev/null
+++ b/modules/stock_package_shipping/tryton.cfg
@@ -0,0 +1,16 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ res
+ carrier
+ product
+ stock
+ stock_package
+ stock_shipment_measurements
+ stock_shipment_cost
+ product_measurements
+xml:
+ carrier.xml
+ stock.xml
+ message.xml
diff --git a/modules/stock_package_shipping/view/carrier_form.xml b/modules/stock_package_shipping/view/carrier_form.xml
new file mode 100644
index 0000000000..aeae5348ed
--- /dev/null
+++ b/modules/stock_package_shipping/view/carrier_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping/view/carrier_tree.xml b/modules/stock_package_shipping/view/carrier_tree.xml
new file mode 100644
index 0000000000..e4f6c45322
--- /dev/null
+++ b/modules/stock_package_shipping/view/carrier_tree.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping/view/package_form.xml b/modules/stock_package_shipping/view/package_form.xml
new file mode 100644
index 0000000000..dcfc93e15b
--- /dev/null
+++ b/modules/stock_package_shipping/view/package_form.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping/view/package_list.xml b/modules/stock_package_shipping/view/package_list.xml
new file mode 100644
index 0000000000..df6e5598c4
--- /dev/null
+++ b/modules/stock_package_shipping/view/package_list.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping/view/package_type_form.xml b/modules/stock_package_shipping/view/package_type_form.xml
new file mode 100644
index 0000000000..5427708fff
--- /dev/null
+++ b/modules/stock_package_shipping/view/package_type_form.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping/view/shipment_in_return_form.xml b/modules/stock_package_shipping/view/shipment_in_return_form.xml
new file mode 100644
index 0000000000..eefd7637b4
--- /dev/null
+++ b/modules/stock_package_shipping/view/shipment_in_return_form.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping/view/shipment_out_form.xml b/modules/stock_package_shipping/view/shipment_out_form.xml
new file mode 100644
index 0000000000..cb35f40339
--- /dev/null
+++ b/modules/stock_package_shipping/view/shipment_out_form.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping_dpd/.drone.yml b/modules/stock_package_shipping_dpd/.drone.yml
new file mode 100644
index 0000000000..7b87e59d53
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/.drone.yml
@@ -0,0 +1,71 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID DPD_USER_ID DPD_PASSWORD
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ secrets: [ dpd_user_id, dpd_password ]
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_package_shipping_dpd/.flake8 b/modules/stock_package_shipping_dpd/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_package_shipping_dpd/.isort.cfg b/modules/stock_package_shipping_dpd/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_package_shipping_dpd/CHANGELOG b/modules/stock_package_shipping_dpd/CHANGELOG
new file mode 100644
index 0000000000..d2b9f23d2a
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/CHANGELOG
@@ -0,0 +1,47 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Add notification preference
+* Use contact mechanism from address
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+* Allow choosing the DPD product and formats
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+* Use total weight of package
+
+Version 4.2.0 - 2016-11-28
+* Initial release
diff --git a/modules/stock_package_shipping_dpd/COPYRIGHT b/modules/stock_package_shipping_dpd/COPYRIGHT
new file mode 100644
index 0000000000..1a03f5236a
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2016-2022 B2CK.
+Copyright (C) 2016-2022 Nicolas Évrard.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_package_shipping_dpd/LICENSE b/modules/stock_package_shipping_dpd/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_package_shipping_dpd/MANIFEST.in b/modules/stock_package_shipping_dpd/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_package_shipping_dpd/README.rst b/modules/stock_package_shipping_dpd/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_package_shipping_dpd/__init__.py b/modules/stock_package_shipping_dpd/__init__.py
new file mode 100644
index 0000000000..a4af86cb24
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/__init__.py
@@ -0,0 +1,20 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import carrier, stock
+
+
+def register():
+ Pool.register(
+ carrier.CredentialDPD,
+ carrier.Carrier,
+ stock.Package,
+ stock.ShipmentOut,
+ stock.ShipmentInReturn,
+ module='stock_package_shipping_dpd', type_='model')
+ Pool.register(
+ stock.CreateShipping,
+ stock.CreateDPDShipping,
+ module='stock_package_shipping_dpd', type_='wizard')
diff --git a/modules/stock_package_shipping_dpd/carrier.py b/modules/stock_package_shipping_dpd/carrier.py
new file mode 100644
index 0000000000..a1025d5711
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/carrier.py
@@ -0,0 +1,124 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import locale
+
+from zeep.exceptions import Fault
+
+from trytond.i18n import gettext
+from trytond.model import (
+ MatchMixin, ModelSQL, ModelView, fields, sequence_ordered)
+from trytond.pool import PoolMeta
+from trytond.pyson import Eval
+
+from .configuration import LOGIN_SERVICE, get_client
+from .exceptions import DPDError
+
+
+class CredentialDPD(sequence_ordered(), ModelSQL, ModelView, MatchMixin):
+ 'DPD Credential'
+ __name__ = 'carrier.credential.dpd'
+
+ company = fields.Many2One('company.company', 'Company')
+ user_id = fields.Char('User ID', required=True, strip=False)
+ password = fields.Char('Password', required=True, strip=False)
+ server = fields.Selection([
+ ('testing', 'Testing'),
+ ('production', 'Production'),
+ ], 'Server')
+ depot = fields.Char('Depot', readonly=True, strip=False)
+ token = fields.Char('Token', readonly=True, strip=False)
+
+ @classmethod
+ def default_server(cls):
+ return 'testing'
+
+ def update_token(self):
+ auth_client = get_client(self.server, LOGIN_SERVICE)
+ lang = (self.company.party.lang.code
+ if self.company.party.lang else 'en')
+ lang = locale.normalize(lang)[:5]
+ try:
+ result = auth_client.service.getAuth(
+ delisId=self.user_id, password=self.password,
+ messageLanguage=lang)
+ except Fault as e:
+ error_message = e.detail[0].find('errorMessage')
+ raise DPDError(
+ gettext('stock_package_shipping_dpd.msg_dpd_webservice_error',
+ message=error_message.text)) from e
+
+ self.token = result.authToken
+ self.depot = result.depot
+ self.save()
+
+
+class Carrier(metaclass=PoolMeta):
+ __name__ = 'carrier'
+
+ dpd_product = fields.Selection([
+ (None, ''),
+ ('CL', "DPD CLASSIC"),
+ ('E830', "DPD 8:30"),
+ ('E10', "DPD 10:00"),
+ ('E12', "DPD 12:00"),
+ ('E18', "DPD 18:00"),
+ ('IE2', "DPD EXPRESS"),
+ ('PL', "DPD PARCEL Letter"),
+ ('PL+', "DPD PARCEL Letter Plus"),
+ ('MAIL', "DPD International Mail"),
+ ], "Product", sort=False, translate=False,
+ states={
+ 'required': Eval('shipping_service') == 'dpd',
+ 'invisible': Eval('shipping_service') != 'dpd',
+ })
+ dpd_printer_language = fields.Selection([
+ (None, ''),
+ ('PDF', "PDF"),
+ ('ZPL', "ZPL"),
+ ], "Printer Language", sort=False, translate=False,
+ states={
+ 'required': Eval('shipping_service') == 'dpd',
+ 'invisible': Eval('shipping_service') != 'dpd',
+ })
+ dpd_paper_format = fields.Selection([
+ (None, ''),
+ ('A4', "A4"),
+ ('A6', "A6"),
+ ('A7', "A7"),
+ ], "Paper Format", sort=False, translate=False,
+ states={
+ 'required': Eval('shipping_service') == 'dpd',
+ 'invisible': Eval('shipping_service') != 'dpd',
+ })
+
+ dpd_notification = fields.Selection([
+ (None, ""),
+ ('email', "E-Mail"),
+ ('sms', "SMS"),
+ ], "Notification",
+ states={
+ 'invisible': Eval('shipping_service') != 'dpd',
+ },
+ help="The preferred notification channel.\n"
+ "Leave empty for no notification.")
+
+ @classmethod
+ def __setup__(cls):
+ super(Carrier, cls).__setup__()
+ cls.shipping_service.selection.append(('dpd', 'DPD'))
+
+ @classmethod
+ def view_attributes(cls):
+ return super().view_attributes() + [
+ ("/form/separator[@id='dpd']", 'states', {
+ 'invisible': Eval('shipping_service') != 'dpd',
+ }),
+ ]
+
+ @property
+ def shipping_label_mimetype(self):
+ mimetype = super().shipping_label_mimetype
+ if self.shipping_service == 'dpd':
+ mimetype = 'application/pdf'
+ return mimetype
diff --git a/modules/stock_package_shipping_dpd/carrier.xml b/modules/stock_package_shipping_dpd/carrier.xml
new file mode 100644
index 0000000000..c836e377a4
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/carrier.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+ carrier
+
+ carrier_form
+
+
+
+ carrier.credential.dpd
+ form
+ dpd_credential_form
+
+
+ carrier.credential.dpd
+ tree
+ dpd_credential_list
+
+
+
+ DPD Credentials
+ carrier.credential.dpd
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping_dpd/configuration.py b/modules/stock_package_shipping_dpd/configuration.py
new file mode 100644
index 0000000000..ab935f0838
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/configuration.py
@@ -0,0 +1,30 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from urllib.parse import urljoin
+
+from zeep import Client
+from zeep.transports import Transport
+
+from trytond.config import config
+
+SERVER_URLS = {
+ 'testing': 'https://public-ws-stage.dpd.com/services/',
+ 'production': 'https://public-ws.dpd.com/services/',
+ }
+
+LOGIN_SERVICE = 'LoginService/V2_0?wsdl'
+SHIPMENT_SERVICE = 'ShipmentService/V3_2?wsdl'
+TIMEOUT = config.get(
+ 'stock_package_shipping_dpd', 'requests_timeout', default=300)
+
+
+def get_client(server, service):
+ api_base_url = config.get('stock_package_shipping_dpd',
+ server, default=SERVER_URLS[server])
+ url = urljoin(api_base_url, service)
+ # Disable the cache for testing because zeep's bug
+ # https://github.com/mvantellingen/python-zeep/issues/48
+ # which makes testing environments fail
+ transport = (Transport(cache=None, operation_timeout=TIMEOUT)
+ if url.startswith(SERVER_URLS['testing']) else None)
+ return Client(url, transport=transport)
diff --git a/modules/stock_package_shipping_dpd/doc/index.rst b/modules/stock_package_shipping_dpd/doc/index.rst
new file mode 100644
index 0000000000..903254ebfe
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/doc/index.rst
@@ -0,0 +1,31 @@
+Stock Package Shipping DPD Module
+#################################
+
+The Stock Package Shipping DPD module allows you to generate the DPD label
+using the DPD webservices.
+DPD has many different web services, the module supports:
+
+- `LoginService 2.0 `_
+- `ShipmentService 3.2 `_
+
+Carrier Credential
+******************
+
+This model allows to define the credential used to connect the DPD API.
+The credentials will be automatically retrieved based on the company of the
+Shipment.
+
+- *Company*: The company for which those credentials are valid
+- *User ID*: The User ID provided by DPD.
+- *Password*: The Password used to access the DPD API.
+- *Server*: Are those credentials used for accessing the Testing or the
+ Production server.
+
+Carrier
+*******
+
+The Carrier model is extended with the following fields:
+
+- *Product*: The DPD product requested.
+- *Printer Language*: The type of file used for the label sent by DPD
+- *Paper Format*: The format of the label sent by DPD
diff --git a/modules/stock_package_shipping_dpd/exceptions.py b/modules/stock_package_shipping_dpd/exceptions.py
new file mode 100644
index 0000000000..d3cb0d2c64
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/exceptions.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.exceptions import UserError
+
+
+class DPDError(UserError):
+ pass
diff --git a/modules/stock_package_shipping_dpd/locale/bg.po b/modules/stock_package_shipping_dpd/locale/bg.po
new file mode 100644
index 0000000000..10f4922dcc
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/bg.po
@@ -0,0 +1,121 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr "Управление на производство"
+
+#, fuzzy
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Фирма"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "Парола"
+
+#, fuzzy
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr "Сървър"
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Create DPD Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr "Управление на производство"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr ""
diff --git a/modules/stock_package_shipping_dpd/locale/ca.po b/modules/stock_package_shipping_dpd/locale/ca.po
new file mode 100644
index 0000000000..419961fb48
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/ca.po
@@ -0,0 +1,123 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr "Notificació"
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr "Format paper"
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr "Idioma de la impressió"
+
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr "Producte"
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr "Dipòsit"
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "Contrasenya"
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr "Servidor"
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr "Token"
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr "Identificador usuari"
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+"El canal de notificació preferit. \n"
+"Deixeu-ho en blanc per desactivar la notificació."
+
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "Credencial DPD"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Crea enviaments DPD per paquets"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "Credencials DPD"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr "La identificació DPD ha fallat amb les credencials \"%(credential)s\"."
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"La crida al servei web DPD ha fallat amb el següent missatge d'error:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+"No podeu crear el enviament per l'albarà \"%(shipment)s\" perquè ja té un "
+"número de referència."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+"Per validar l'albarà \"%(shipment)s\" heu d'establir una direcció al "
+"magatzem \"%(warehouse)s\"."
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "Credencials DPD"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr "Correu electrònic"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr "SMS"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr "DPD"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr "Producció"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr "Proves"
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr "Informació de les credencials"
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr "DPD"
diff --git a/modules/stock_package_shipping_dpd/locale/cs.po b/modules/stock_package_shipping_dpd/locale/cs.po
new file mode 100644
index 0000000000..03b386e84f
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/cs.po
@@ -0,0 +1,116 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Create DPD Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr ""
diff --git a/modules/stock_package_shipping_dpd/locale/de.po b/modules/stock_package_shipping_dpd/locale/de.po
new file mode 100644
index 0000000000..73ce009582
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/de.po
@@ -0,0 +1,123 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr "Benachrichtigung"
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr "Papierformat"
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr "Druckersprache"
+
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr "Artikel"
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Unternehmen"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr "Depot"
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "Passwort"
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr "Server"
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr "Token"
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr "Benutzer ID"
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+"Der bevorzugte Benachrichtigungskanal.\n"
+"Leer lassen für keine Benachrichtigung."
+
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "DPD Anmeldedaten"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "DPD Versand für Pakete erstellen"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Anmeldedaten"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr "Der DPD Login mit den Anmeldedaten \"%(credential)s\" ist fehlgeschlagen."
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"Der Aufruf des DPD-Webservice schlug fehl mit der folgenden Fehlermeldung:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+"Für die Lieferung \"%(shipment)s\" kann keine Sendung erstellt werden, da "
+"sie bereits eine Referenznummer hat."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+"Um die Lieferung \"%(shipment)s\" validieren zu können, muss eine Adresse "
+"für den Logistikstandort \"%(warehouse)s\" erfasst werden."
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Anmeldedaten"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr "E-Mail"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr "SMS"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr "DPD"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr "Produktivumgebung"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr "Testumgebung"
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr "Anmeldedaten"
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr "DPD"
diff --git a/modules/stock_package_shipping_dpd/locale/es.po b/modules/stock_package_shipping_dpd/locale/es.po
new file mode 100644
index 0000000000..6916b93f8d
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/es.po
@@ -0,0 +1,123 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr "Notificación"
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr "Formato papel"
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr "Idioma de la impresión"
+
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr "Producto"
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr "Deposito"
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "Contraseña"
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr "Servidor"
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr "Token"
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr "Identificador de usuario"
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+"El canal de notificación preferido. \n"
+"Dejare en blanco para desactivar la notificación."
+
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "Credencial DPD"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Crear envíos DPD para paquetes"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "Credenciales DPD"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr "La identificación DPD ha fallado con las credenciales \"%(credential)s\"."
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"La llamada al servicio web DPD ha fallado con el siguiente mensaje de error:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+"No puede crear el envío para el albarán \"%(shipment)s\" porque ya tiene un "
+"número de referencia."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+"Para validar el albarán \"%(shipment)s\" debe establecer una dirección en el"
+" almacén \"%(warehouse)s\"."
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "Credenciales DPD"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr "Correo electrónico"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr "SMS"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr "DPD"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr "Producción"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr "Pruebas"
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr "Información de las credenciales"
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr "DPD"
diff --git a/modules/stock_package_shipping_dpd/locale/es_419.po b/modules/stock_package_shipping_dpd/locale/es_419.po
new file mode 100644
index 0000000000..65d046dc27
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/es_419.po
@@ -0,0 +1,115 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr "Depósito"
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr ""
diff --git a/modules/stock_package_shipping_dpd/locale/et.po b/modules/stock_package_shipping_dpd/locale/et.po
new file mode 100644
index 0000000000..db0146d2d4
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/et.po
@@ -0,0 +1,117 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr "Tootmine"
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Ettevõte"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "Salasõna"
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr "Server"
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr "Token"
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr "Kasutaja ID"
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "DPD viide"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Loo DPD saadetis"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD viide"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD viide"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr "DPD"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr "Tootmine"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr "Testimine"
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr "Viite info"
+
+#, fuzzy
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr "DPD"
diff --git a/modules/stock_package_shipping_dpd/locale/fa.po b/modules/stock_package_shipping_dpd/locale/fa.po
new file mode 100644
index 0000000000..bfdd5c7324
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/fa.po
@@ -0,0 +1,124 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr "تهیه کننده"
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "شرکت"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr "دپو"
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "کلمه عبور"
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr "سرور"
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr "توکن"
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr "شناسه کاربر"
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "گواهی نامه DPD"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "ایجاد حمل ونقل DPD برای بسته ها"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "گواهی نامه های DPD"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"تماس با وب سرویس DPD با پیغام خطای زیر انجام نشد :\n"
+"\"%s\""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+"شما نمی توانید حمل و نقل را برای حمل و نقل :\"%(shipment)s\" ایجاد کنید زیرا"
+" قبلا یک شماره مرجع است."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+"برای تایید حمل و نقل :\"%(shipment)s\" شما باید یک آدرس را در "
+"انبار:\"%(warehouse)s\" تنظیم کنید."
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "گواهی نامه های DPD"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr "DPD"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr "تهیه کننده"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr "آزمایش"
+
+#, fuzzy
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr "اطلاعات گواهی نامه"
+
+#, fuzzy
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr "DPD"
diff --git a/modules/stock_package_shipping_dpd/locale/fi.po b/modules/stock_package_shipping_dpd/locale/fi.po
new file mode 100644
index 0000000000..03b386e84f
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/fi.po
@@ -0,0 +1,116 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Create DPD Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr ""
diff --git a/modules/stock_package_shipping_dpd/locale/fr.po b/modules/stock_package_shipping_dpd/locale/fr.po
new file mode 100644
index 0000000000..f6e415e86a
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/fr.po
@@ -0,0 +1,125 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr "Notification"
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr "Format papier"
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr "Langue de l'imprimante"
+
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr "Produit"
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Société"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr "Dépôt"
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "Mot de passe"
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr "Serveur"
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr "Jeton"
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr "ID d'utilisateur"
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+"Le canal de notification préféré.\n"
+"Laissez vide pour aucune notification."
+
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "Identifiant DPD"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Créer la livraison DPD pour les emballages"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "Identifiants DPD"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+"La connexion DPD a échoué avec les informations d'identification "
+"« %(credential)s »."
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"L'appel au service web de DPD a échoué avec le message d'erreur suivant :\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+"Vous ne pouvez pas créer de livraison pour l'expédition « %(shipment)s » car"
+" elle a déjà un numéro de référence."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+"Pour valider la livraison « %(shipment)s », vous devez définir une adresse "
+"pour l'entrepôt « %(warehouse)s »."
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "Identifiants DPD"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr "E-Mail"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr "SMS"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr "DPD"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr "Essai"
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr "Informations d'identification"
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr "DPD"
diff --git a/modules/stock_package_shipping_dpd/locale/hu.po b/modules/stock_package_shipping_dpd/locale/hu.po
new file mode 100644
index 0000000000..6ec177b865
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/hu.po
@@ -0,0 +1,120 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr "Termelés"
+
+#, fuzzy
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Társaság"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "Jelszó"
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Create DPD Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr "Termelés"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr ""
diff --git a/modules/stock_package_shipping_dpd/locale/id.po b/modules/stock_package_shipping_dpd/locale/id.po
new file mode 100644
index 0000000000..9eca4edbc9
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/id.po
@@ -0,0 +1,116 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr "Produk"
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Perusahaan"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "Kata sandi"
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr "Server"
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr "DPD"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr "Produksi"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr "Testing"
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr "DPD"
diff --git a/modules/stock_package_shipping_dpd/locale/it.po b/modules/stock_package_shipping_dpd/locale/it.po
new file mode 100644
index 0000000000..de399dc73c
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/it.po
@@ -0,0 +1,117 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Azienda"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "Password"
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Create DPD Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr ""
diff --git a/modules/stock_package_shipping_dpd/locale/lo.po b/modules/stock_package_shipping_dpd/locale/lo.po
new file mode 100644
index 0000000000..2e8e21e3fc
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/lo.po
@@ -0,0 +1,119 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr "ຜະລິດຕະພັນ"
+
+#, fuzzy
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "ຫ້ອງການ/ສຳນັກງານ"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Create DPD Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr "ຜະລິດຕະພັນ"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr ""
diff --git a/modules/stock_package_shipping_dpd/locale/lt.po b/modules/stock_package_shipping_dpd/locale/lt.po
new file mode 100644
index 0000000000..0cd345c731
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/lt.po
@@ -0,0 +1,116 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Organizacija"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr "Naudotojo ID"
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Create DPD Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr ""
diff --git a/modules/stock_package_shipping_dpd/locale/nl.po b/modules/stock_package_shipping_dpd/locale/nl.po
new file mode 100644
index 0000000000..8b8dfe145b
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/nl.po
@@ -0,0 +1,123 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr "Melding"
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr "Papierformaat"
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr "Printertaal"
+
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr "Product"
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Bedrijf"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr "Magazijn"
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "Wachtwoord"
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr "Server"
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr "Token"
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr "Gebruiker ID"
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+"Voorkeur welk soort melding te gebruiken.\n"
+"Laat leeg om meldingen uit te schakelen."
+
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "DPD-referentie"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Maak een DPD-verzending voor de pakketten"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr "DPD-aanmelding is mislukt met referentie %(credential)s\"."
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"DPD webservice-oproep mislukt met het volgende foutbericht:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+"U kunt geen verzending voor zending \"%(shipment)s\" maken omdat deze al een"
+" referentienummer heeft."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+"Om zending \"%(shipment)s\" te valideren, moet u een adres voor magazijn "
+"\"%(warehouse)s\" instellen."
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr "E-mail"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr "SMS"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr "DPD"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr "Productie"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr "Testen"
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr "Referentiegegevens"
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr "DPD"
diff --git a/modules/stock_package_shipping_dpd/locale/pl.po b/modules/stock_package_shipping_dpd/locale/pl.po
new file mode 100644
index 0000000000..f4c3185f2b
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/pl.po
@@ -0,0 +1,120 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr "Produkcja"
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Firma"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "Hasło"
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr "Serwer"
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr "Token"
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr "ID użytkownika"
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Create DPD Shipping for Packages"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr "DPD"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr "Produkcja"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr "DPD"
diff --git a/modules/stock_package_shipping_dpd/locale/pt.po b/modules/stock_package_shipping_dpd/locale/pt.po
new file mode 100644
index 0000000000..3403773c18
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/pt.po
@@ -0,0 +1,125 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr "Produção"
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr "Depósito"
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "Senha"
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr "Servidor"
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr "Token:"
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr "ID de usuário"
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "Credencial DPD"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Create DPD Shipping for Packages"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"A chamada ao serviço web DPD falhou com a mensagem de erro:\n"
+"\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr "DPD"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr "Produção"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr "Testando"
+
+#, fuzzy
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr "Informações da Credencial"
+
+#, fuzzy
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr "DPD"
diff --git a/modules/stock_package_shipping_dpd/locale/ro.po b/modules/stock_package_shipping_dpd/locale/ro.po
new file mode 100644
index 0000000000..a44566bf05
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/ro.po
@@ -0,0 +1,115 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Companie"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr ""
diff --git a/modules/stock_package_shipping_dpd/locale/ru.po b/modules/stock_package_shipping_dpd/locale/ru.po
new file mode 100644
index 0000000000..5830f30f07
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/ru.po
@@ -0,0 +1,121 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr "Производство"
+
+#, fuzzy
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Учет.орг."
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "Пароль"
+
+#, fuzzy
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr "Сервер"
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Create DPD Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr "Производство"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr ""
diff --git a/modules/stock_package_shipping_dpd/locale/sl.po b/modules/stock_package_shipping_dpd/locale/sl.po
new file mode 100644
index 0000000000..836cfe065b
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/sl.po
@@ -0,0 +1,125 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr "Produkcijski"
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr "Družba"
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr "Skladišče"
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "Geslo"
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr "Strežnik"
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr "Žeton"
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr "Uporabnik"
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "DPD prijava"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Create DPD Shipping for Packages"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"Sporočilo napake pri klicu DPD spletne storitve:\n"
+"\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr "DPD"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr "Produkcijski"
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr "Preizkusni"
+
+#, fuzzy
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr "Prijavni podatki"
+
+#, fuzzy
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr "DPD"
diff --git a/modules/stock_package_shipping_dpd/locale/tr.po b/modules/stock_package_shipping_dpd/locale/tr.po
new file mode 100644
index 0000000000..03b386e84f
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/tr.po
@@ -0,0 +1,116 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Create DPD Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr ""
diff --git a/modules/stock_package_shipping_dpd/locale/uk.po b/modules/stock_package_shipping_dpd/locale/uk.po
new file mode 100644
index 0000000000..565bab6df3
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/uk.po
@@ -0,0 +1,115 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr ""
diff --git a/modules/stock_package_shipping_dpd/locale/zh_CN.po b/modules/stock_package_shipping_dpd/locale/zh_CN.po
new file mode 100644
index 0000000000..ed9c44d692
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/locale/zh_CN.po
@@ -0,0 +1,117 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,dpd_notification:"
+msgid "Notification"
+msgstr ""
+
+msgctxt "field:carrier,dpd_paper_format:"
+msgid "Paper Format"
+msgstr ""
+
+msgctxt "field:carrier,dpd_printer_language:"
+msgid "Printer Language"
+msgstr ""
+
+msgctxt "field:carrier,dpd_product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,depot:"
+msgid "Depot"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier.credential.dpd,password:"
+msgid "Password"
+msgstr "密码"
+
+msgctxt "field:carrier.credential.dpd,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,token:"
+msgid "Token"
+msgstr ""
+
+msgctxt "field:carrier.credential.dpd,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "help:carrier,dpd_notification:"
+msgid ""
+"The preferred notification channel.\n"
+"Leave empty for no notification."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.dpd,name:"
+msgid "DPD Credential"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_dpd_wizard"
+msgid "Create DPD Shipping for Packages"
+msgstr "Create DPD Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "model:ir.message,text:msg_dpd_login_error"
+msgid "DPD login failed with credential \"%(credential)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_dpd_webservice_error"
+msgid ""
+"DPD webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on the "
+"warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_dpd_credential_form"
+msgid "DPD Credentials"
+msgstr "DPD Credentials"
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "E-Mail"
+msgstr ""
+
+msgctxt "selection:carrier,dpd_notification:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "DPD"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.dpd,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.dpd:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "DPD"
+msgstr ""
diff --git a/modules/stock_package_shipping_dpd/message.xml b/modules/stock_package_shipping_dpd/message.xml
new file mode 100644
index 0000000000..cc65a45e82
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/message.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+ DPD webservice call failed with the following error message:
+%(message)s
+
+
+ DPD login failed with credential "%(credential)s".
+
+
+ To validate shipment "%(shipment)s" you must set an address on the warehouse "%(warehouse)s".
+
+
+ You cannot create shipping for shipment "%(shipment)s" because it has already a reference number.
+
+
+
diff --git a/modules/stock_package_shipping_dpd/setup.py b/modules/stock_package_shipping_dpd/setup.py
new file mode 100755
index 0000000000..4ce89a5deb
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/setup.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_package_shipping_dpd'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = ['zeep >= 0.12', 'PyPDF2', 'lxml']
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [
+ get_require_version('proteus'),
+ get_require_version('trytond_sale'),
+ get_require_version('trytond_sale_shipment_cost'),
+ ]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='DPD connector for the Tryton application platform',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": (
+ 'https://hg.tryton.org/modules/stock_package_shipping_dpd'),
+ },
+ keywords='tryton stock package shipping dpd',
+ package_dir={'trytond.modules.stock_package_shipping_dpd': '.'},
+ packages=(
+ ['trytond.modules.stock_package_shipping_dpd']
+ + ['trytond.modules.stock_package_shipping_dpd.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_package_shipping_dpd': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_package_shipping_dpd = trytond.modules.stock_package_shipping_dpd
+ """,
+ )
diff --git a/modules/stock_package_shipping_dpd/stock.py b/modules/stock_package_shipping_dpd/stock.py
new file mode 100644
index 0000000000..fd4c0bb843
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/stock.py
@@ -0,0 +1,319 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import locale
+from io import BytesIO
+from itertools import zip_longest
+
+from lxml import etree
+from PyPDF2 import PdfFileReader, PdfFileWriter
+from zeep.exceptions import Fault
+
+from trytond.i18n import gettext
+from trytond.model import fields
+from trytond.model.exceptions import AccessError
+from trytond.modules.stock_package_shipping.exceptions import (
+ PackingValidationError)
+from trytond.pool import Pool, PoolMeta
+from trytond.transaction import Transaction
+from trytond.wizard import StateAction, StateTransition, Wizard
+
+from .configuration import SHIPMENT_SERVICE, get_client
+from .exceptions import DPDError
+
+TRACKING_URL = 'https://tracking.dpd.de/status/%(code)s/parcel/%(reference)s'
+
+
+class Package(metaclass=PoolMeta):
+ __name__ = 'stock.package'
+
+ def get_shipping_tracking_url(self, name):
+ pool = Pool()
+ ShipmentOut = pool.get('stock.shipment.out')
+ ShipmentInReturn = pool.get('stock.shipment.in.return')
+ url = super().get_shipping_tracking_url(name)
+ if (self.shipping_reference
+ and self.shipment
+ and self.shipment.id >= 0
+ and self.shipment.carrier
+ and self.shipment.carrier.shipping_service == 'dpd'):
+ party = address = None
+ if isinstance(self.shipment, ShipmentOut):
+ party = self.shipment.customer
+ address = self.shipment.delivery_address
+ elif isinstance(self.shipment, ShipmentInReturn):
+ party = self.shipment.supplier
+ address = self.shipment.delivery_address
+ if party and party.lang:
+ lang_code = party.lang.code
+ else:
+ lang_code = Transaction().language
+ if address and address.country:
+ code = '_'.join(
+ (lang_code.split('_')[0], address.country.code))
+ else:
+ code = lang_code
+ url = TRACKING_URL % {
+ 'code': code,
+ 'reference': self.shipping_reference,
+ }
+ return url
+
+
+class ShippingDPDMixin:
+ __slots__ = ()
+
+ def validate_packing_dpd(self):
+ warehouse = self.shipping_warehouse
+ if not warehouse.address:
+ raise PackingValidationError(
+ gettext('stock_package_shipping_dpd'
+ '.msg_warehouse_address_required',
+ shipment=self.rec_name,
+ warehouse=warehouse.rec_name))
+
+
+class ShipmentOut(ShippingDPDMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out'
+
+
+class ShipmentInReturn(ShippingDPDMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in.return'
+
+
+class CreateShipping(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.create_shipping'
+
+ dpd = StateAction(
+ 'stock_package_shipping_dpd.act_create_shipping_dpd_wizard')
+
+ def transition_start(self):
+ next_state = super(CreateShipping, self).transition_start()
+ if self.record.carrier.shipping_service == 'dpd':
+ next_state = 'dpd'
+ return next_state
+
+ def do_dpd(self, action):
+ ctx = Transaction().context
+ return action, {
+ 'model': ctx['active_model'],
+ 'id': ctx['active_id'],
+ 'ids': [ctx['active_id']],
+ }
+
+
+class CreateDPDShipping(Wizard):
+ 'Create DPD Shipping'
+ __name__ = 'stock.shipment.create_shipping.dpd'
+
+ start = StateTransition()
+
+ def transition_start(self):
+ pool = Pool()
+ Package = pool.get('stock.package')
+
+ shipment = self.record
+ if shipment.reference:
+ raise AccessError(
+ gettext('stock_package_shipping_dpd'
+ '.msg_shipment_has_reference_number',
+ shipment=shipment.rec_name))
+
+ credential = self.get_credential(shipment)
+ if not credential.depot or not credential.token:
+ credential.update_token()
+
+ carrier = shipment.carrier
+ shipping_client = get_client(credential.server, SHIPMENT_SERVICE)
+ print_options = self.get_print_options(shipment)
+ packages = shipment.root_packages
+ shipment_data = self.get_shipment_data(credential, shipment, packages)
+
+ count = 0
+ while count < 2:
+ lang = (credential.company.party.lang.code
+ if credential.company.party.lang else 'en')
+ lang = locale.normalize(lang)[:5]
+ authentication = {
+ 'delisId': credential.user_id,
+ 'authToken': credential.token,
+ 'messageLanguage': lang,
+ }
+ try:
+ shipment_response = shipping_client.service.storeOrders(
+ print_options, shipment_data, _soapheaders={
+ 'authentication': authentication,
+ })
+ break
+ except Fault as e:
+ if e.detail:
+ tag = etree.QName(e.detail[0].tag)
+ if tag.localname == 'authenticationFault':
+ count += 1
+ credential.update_token()
+ continue
+ raise DPDError(gettext(
+ 'stock_package_shipping_dpd.'
+ 'msg_dpd_webservice_error',
+ message=e.message)) from e
+ else:
+ raise DPDError(
+ gettext('stock_package_shipping_dpd.msg_dpd_login_error',
+ credential=credential.rec_name))
+
+ response, = shipment_response.shipmentResponses
+ if response.faults:
+ message = '\n'.join(f.message for f in response.faults)
+ raise DPDError(
+ gettext('stock_package_shipping_dpd.msg_dpd_webservice_error',
+ message=message))
+
+ labels = []
+ labels_pdf = BytesIO(shipment_response.parcellabelsPDF)
+ reader = PdfFileReader(labels_pdf)
+ for page_num in range(reader.getNumPages()):
+ new_pdf = PdfFileWriter()
+ new_label = BytesIO()
+ new_pdf.addPage(reader.getPage(page_num))
+ new_pdf.write(new_label)
+ labels.append(new_label)
+
+ shipment.reference = response.mpsId
+ parcels = response.parcelInformation
+ for package, label, parcel in zip_longest(packages, labels, parcels):
+ package.shipping_label = fields.Binary.cast(label.getvalue())
+ package.shipping_label_mimetype = (
+ carrier.shipping_label_mimetype)
+ package.shipping_reference = parcel.parcelLabelNumber
+ Package.save(packages)
+ shipment.save()
+
+ return 'end'
+
+ def get_credential_pattern(self, shipment):
+ return {
+ 'company': shipment.company.id,
+ }
+
+ def get_credential(self, shipment):
+ pool = Pool()
+ DPDCredential = pool.get('carrier.credential.dpd')
+
+ credential_pattern = self.get_credential_pattern(shipment)
+ for credential in DPDCredential.search([]):
+ if credential.match(credential_pattern):
+ return credential
+
+ def get_print_options(self, shipment):
+ return {
+ 'printerLanguage': shipment.carrier.dpd_printer_language,
+ 'paperFormat': shipment.carrier.dpd_paper_format,
+ }
+
+ def shipping_party(self, party, address, usage=None):
+ shipping_party = {
+ 'name1': address.party_full_name[:35],
+ 'name2': '',
+ 'street': ' '.join((address.street or '').splitlines())[:35],
+ 'country': address.country.code if address.country else '',
+ 'zipCode': address.postal_code[:9],
+ 'city': address.city[:35],
+ }
+ if party.full_name != address.party_full_name:
+ shipping_party['name2'] = party.full_name[:35]
+
+ phone = address.contact_mechanism_get({'phone', 'mobile'}, usage=usage)
+ if phone and len(phone.value) <= 30:
+ shipping_party['phone'] = phone.value
+ email = address.contact_mechanism_get('email', usage=usage)
+ if email and len(email.value) <= 50:
+ shipping_party['email'] = email.value
+
+ return shipping_party
+
+ def get_parcel(self, package):
+ pool = Pool()
+ UoM = pool.get('product.uom')
+ ModelData = pool.get('ir.model.data')
+
+ cm = UoM(ModelData.get_id('product', 'uom_centimeter'))
+
+ parcel = {}
+
+ if package.total_weight:
+ # in grams rounded in 10 gram units
+ weight = int(package.total_weight * 10) * 10
+ if weight < 1000000000:
+ parcel['weight'] = weight
+
+ if (package.length is not None
+ and package.width is not None
+ and package.height is not None):
+ length = UoM.compute_qty(
+ package.length_uom, package.length, cm)
+ width = UoM.compute_qty(
+ package.width_uom, package.width, cm)
+ height = UoM.compute_qty(
+ package.height_uom, package.height, cm)
+ if length < 1000 and width < 1000 and height < 1000:
+ parcel['volume'] = int(
+ '%03i%03i%03i' % (length, width, height))
+
+ return parcel
+
+ def get_shipment_data(self, credential, shipment, packages):
+ return {
+ 'generalShipmentData': {
+ 'identificationNumber': shipment.number,
+ 'sendingDepot': credential.depot,
+ 'product': shipment.carrier.dpd_product,
+ 'sender': self.shipping_party(
+ shipment.company.party,
+ shipment.shipping_warehouse.address),
+ 'recipient': self.shipping_party(
+ shipment.shipping_to, shipment.shipping_to_address),
+ },
+ 'parcels': [self.get_parcel(p) for p in packages],
+ 'productAndServiceData': {
+ 'orderType': 'consignment',
+ **self.get_notification(shipment),
+ },
+ }
+
+ def get_notification(self, shipment, usage=None):
+ carrier = shipment.carrier
+ if not carrier.dpd_notification:
+ return {}
+ party = shipment.shipping_to
+ if party and party.lang:
+ lang_code = party.lang.code
+ else:
+ lang_code = Transaction().language
+ lang_code = lang_code.upper()
+ channel2type = {
+ 'sms': {'mobile'},
+ }
+
+ channels = [
+ (1, 'email'),
+ (3, 'sms'),
+ ]
+ if carrier.dpd_notification == 'sms':
+ channels = reversed(channels)
+
+ for channel_id, channel in channels:
+ mechanism = party.contact_mechanism_get(
+ channel2type.get(channel, channel), usage=usage)
+ if not mechanism:
+ continue
+ value = mechanism.value
+ if len(value) > 50:
+ continue
+ return {
+ 'predict': {
+ 'channel': channel_id,
+ 'value': value,
+ 'language': lang_code,
+ },
+ }
+ return {}
diff --git a/modules/stock_package_shipping_dpd/stock.xml b/modules/stock_package_shipping_dpd/stock.xml
new file mode 100644
index 0000000000..2c4b020979
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/stock.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+ Create DPD Shipping for Packages
+ stock.shipment.create_shipping.dpd
+
+
+
diff --git a/modules/stock_package_shipping_dpd/tests/__init__.py b/modules/stock_package_shipping_dpd/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_package_shipping_dpd/tests/scenario_shipping_dpd.rst b/modules/stock_package_shipping_dpd/tests/scenario_shipping_dpd.rst
new file mode 100644
index 0000000000..f1179751cd
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/tests/scenario_shipping_dpd.rst
@@ -0,0 +1,231 @@
+========================================
+Stock Package Shipping with DPD scenario
+========================================
+
+Imports::
+
+ >>> import datetime
+ >>> import os
+ >>> from dateutil.relativedelta import relativedelta
+ >>> from decimal import Decimal
+ >>> from operator import attrgetter
+ >>> from proteus import Model, Wizard, Report
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> from trytond.modules.account.tests.tools import create_fiscalyear, \
+ ... create_chart, get_accounts, create_tax
+ >>> from trytond.modules.account_invoice.tests.tools import \
+ ... set_fiscalyear_invoice_sequences, create_payment_term
+ >>> today = datetime.date.today()
+
+Activate modules::
+
+ >>> config = activate_modules(
+ ... ['stock_package_shipping_dpd', 'sale', 'sale_shipment_cost'])
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create fiscal year::
+
+ >>> fiscalyear = set_fiscalyear_invoice_sequences(
+ ... create_fiscalyear(company))
+ >>> fiscalyear.click('create_period')
+
+Create chart of accounts::
+
+ >>> _ = create_chart(company)
+ >>> accounts = get_accounts(company)
+ >>> revenue = accounts['revenue']
+ >>> expense = accounts['expense']
+
+Create a payment term::
+
+ >>> payment_term = create_payment_term()
+ >>> payment_term.save()
+
+Create parties::
+
+ >>> Party = Model.get('party.party')
+ >>> Country = Model.get('country.country')
+
+ >>> belgium = Country(code='BE', name='Belgium')
+ >>> belgium.save()
+ >>> france = Country(code='FR', name='France')
+ >>> france.save()
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+ >>> customer_address = customer.addresses.new()
+ >>> customer_address.street = 'Champs élysées'
+ >>> customer_address.postal_code = '75008'
+ >>> customer_address.city = 'Paris'
+ >>> customer_address.country = france
+ >>> customer_address.save()
+ >>> customer_phone = customer.contact_mechanisms.new(type='mobile')
+ >>> customer_phone.value = '+33 93 842 8862'
+ >>> customer_phone.save()
+
+Set the warehouse address::
+
+ >>> Address = Model.get('party.address')
+ >>> Location = Model.get('stock.location')
+ >>> warehouse, = Location.find([('type', '=', 'warehouse')])
+ >>> company_address = Address()
+ >>> company_address.party = company.party
+ >>> company_address.street = '2 rue de la Centrale'
+ >>> company_address.postal_code = '4000'
+ >>> company_address.city = 'Sclessin'
+ >>> company_address.country = belgium
+ >>> company_address.save()
+ >>> company_phone = company.party.contact_mechanisms.new()
+ >>> company_phone.type = 'phone'
+ >>> company_phone.value = '+32 4 2522122'
+ >>> company_phone.save()
+ >>> warehouse.address = company_address
+ >>> warehouse.save()
+
+Get some units::
+
+ >>> UoM = Model.get('product.uom')
+ >>> cm, = UoM.find([('symbol', '=', 'cm')])
+ >>> g, = UoM.find([('symbol', '=', 'g')])
+
+Create account category::
+
+ >>> ProductCategory = Model.get('product.category')
+ >>> account_category = ProductCategory(name="Account Category")
+ >>> account_category.accounting = True
+ >>> account_category.account_expense = expense
+ >>> account_category.account_revenue = revenue
+ >>> account_category.save()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+ >>> ProductTemplate = Model.get('product.template')
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.salable = True
+ >>> template.weight = 100
+ >>> template.weight_uom = g
+ >>> template.list_price = Decimal('10')
+ >>> template.account_category = account_category
+ >>> template.save()
+ >>> product, = template.products
+
+Create an Inventory::
+
+ >>> Inventory = Model.get('stock.inventory')
+ >>> storage, = Location.find([
+ ... ('code', '=', 'STO'),
+ ... ])
+ >>> inventory = Inventory()
+ >>> inventory.location = storage
+ >>> inventory_line = inventory.lines.new(product=product)
+ >>> inventory_line.quantity = 100.0
+ >>> inventory_line.expected_quantity = 0.0
+ >>> inventory.click('confirm')
+ >>> inventory.state
+ 'done'
+
+Create Package Type::
+
+ >>> PackageType = Model.get('stock.package.type')
+ >>> box = PackageType(
+ ... name='Box',
+ ... length=10, length_uom=cm,
+ ... height=8, height_uom=cm,
+ ... width=5, width_uom=cm)
+ >>> box.save()
+
+Create a DPD Carrier and the related credential::
+
+ >>> Carrier = Model.get('carrier')
+ >>> CarrierSelection = Model.get('carrier.selection')
+ >>> DPDCredential = Model.get('carrier.credential.dpd')
+
+ >>> credential = DPDCredential()
+ >>> credential.company = company
+ >>> credential.user_id = os.getenv('DPD_USER_ID')
+ >>> credential.password = os.getenv('DPD_PASSWORD')
+ >>> credential.server = 'testing'
+ >>> credential.save()
+
+ >>> carrier_product_template = ProductTemplate()
+ >>> carrier_product_template.name = 'DPD Delivery'
+ >>> carrier_product_template.default_uom = unit
+ >>> carrier_product_template.type = 'service'
+ >>> carrier_product_template.salable = True
+ >>> carrier_product_template.list_price = Decimal(20)
+ >>> carrier_product_template.account_category = account_category
+ >>> carrier_product_template.save()
+ >>> carrier_product, = carrier_product_template.products
+
+ >>> dpd = Party(name='DPD')
+ >>> dpd.save()
+
+ >>> carrier = Carrier()
+ >>> carrier.party = dpd
+ >>> carrier.carrier_product = carrier_product
+ >>> carrier.shipping_service = 'dpd'
+ >>> carrier.dpd_product = 'CL'
+ >>> carrier.dpd_printer_language = 'PDF'
+ >>> carrier.dpd_paper_format = 'A6'
+ >>> carrier.dpd_notification = 'sms'
+ >>> carrier.save()
+
+ >>> catchall_selection = CarrierSelection(carrier=carrier)
+ >>> catchall_selection.save()
+
+Create a sale and thus a shipment::
+
+ >>> Sale = Model.get('sale.sale')
+ >>> SaleLine = Model.get('sale.line')
+ >>> sale = Sale()
+ >>> sale.party = customer
+ >>> sale.shipment_address = customer_address
+ >>> sale.payment_term = payment_term
+ >>> sale.invoice_method = 'order'
+ >>> sale.carrier = carrier
+ >>> sale_line = sale.lines.new()
+ >>> sale_line.product = product
+ >>> sale_line.quantity = 2.0
+ >>> sale.click('quote')
+ >>> sale.click('confirm')
+ >>> sale.click('process')
+
+Create the packs and ship the shipment::
+
+ >>> Package = Model.get('stock.package')
+ >>> shipment, = sale.shipments
+ >>> shipment.click('assign_try')
+ True
+ >>> shipment.click('pick')
+ >>> pack = shipment.packages.new()
+ >>> pack.type = box
+ >>> pack_move, = pack.moves.find([])
+ >>> pack.moves.append(pack_move)
+ >>> shipment.click('pack')
+
+ >>> create_shipping = Wizard('stock.shipment.create_shipping', [shipment])
+ >>> shipment.reload()
+ >>> shipment.reference != ''
+ True
+ >>> pack, = shipment.root_packages
+ >>> pack.shipping_label is not None
+ True
+ >>> pack.shipping_label_mimetype
+ 'application/pdf'
+ >>> pack.shipping_reference is not None
+ True
+ >>> pack.shipping_tracking_url.startswith('https://tracking.dpd.de/status/')
+ True
+ >>> pack.shipping_tracking_url.endswith(pack.shipping_reference)
+ True
diff --git a/modules/stock_package_shipping_dpd/tests/test_module.py b/modules/stock_package_shipping_dpd/tests/test_module.py
new file mode 100644
index 0000000000..8754bd8c25
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/tests/test_module.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockPackageShippingDpdTestCase(ModuleTestCase):
+ 'Test Stock Package Shipping Dpd module'
+ module = 'stock_package_shipping_dpd'
+
+
+del ModuleTestCase
diff --git a/modules/stock_package_shipping_dpd/tests/test_scenario.py b/modules/stock_package_shipping_dpd/tests/test_scenario.py
new file mode 100644
index 0000000000..a32779e0c7
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/tests/test_scenario.py
@@ -0,0 +1,10 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import os
+
+from trytond.tests.test_tryton import load_doc_tests
+
+if os.getenv('DPD_USER_ID') and os.getenv('DPD_PASSWORD'):
+ def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_package_shipping_dpd/tox.ini b/modules/stock_package_shipping_dpd/tox.ini
new file mode 100644
index 0000000000..817507dc3d
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_package_shipping_dpd/* -m unittest discover -s tests
+ coverage report --include=./**/stock_package_shipping_dpd/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_package_shipping_dpd/tryton.cfg b/modules/stock_package_shipping_dpd/tryton.cfg
new file mode 100644
index 0000000000..d7bf505f7d
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/tryton.cfg
@@ -0,0 +1,15 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ res
+ party
+ product
+ stock
+ stock_shipment_measurements
+ stock_package
+ stock_package_shipping
+xml:
+ carrier.xml
+ stock.xml
+ message.xml
diff --git a/modules/stock_package_shipping_dpd/view/carrier_form.xml b/modules/stock_package_shipping_dpd/view/carrier_form.xml
new file mode 100644
index 0000000000..e0be4750eb
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/view/carrier_form.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping_dpd/view/dpd_credential_form.xml b/modules/stock_package_shipping_dpd/view/dpd_credential_form.xml
new file mode 100644
index 0000000000..b17a71a93e
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/view/dpd_credential_form.xml
@@ -0,0 +1,17 @@
+
+
+
diff --git a/modules/stock_package_shipping_dpd/view/dpd_credential_list.xml b/modules/stock_package_shipping_dpd/view/dpd_credential_list.xml
new file mode 100644
index 0000000000..3ea329081b
--- /dev/null
+++ b/modules/stock_package_shipping_dpd/view/dpd_credential_list.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping_mygls/.drone.yml b/modules/stock_package_shipping_mygls/.drone.yml
new file mode 100644
index 0000000000..f99c626d17
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/.drone.yml
@@ -0,0 +1,79 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID MYGLS_USERNAME MYGLS_PASSWORD MYGLS_CLIENT_NUMBER
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ secrets: [ mygls_username, mygls_password, mygls_client_number ]
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+ check_doc:
+ image: ${IMAGE}
+ commands:
+ - pip install sphinx
+ - python -m sphinx -T -E -W -n -b html doc _build/html
+ - python -m sphinx -T -E -W -n -b linkcheck doc _build
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_package_shipping_mygls/.flake8 b/modules/stock_package_shipping_mygls/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_package_shipping_mygls/.isort.cfg b/modules/stock_package_shipping_mygls/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_package_shipping_mygls/CHANGELOG b/modules/stock_package_shipping_mygls/CHANGELOG
new file mode 100644
index 0000000000..13acbbdca3
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/CHANGELOG
@@ -0,0 +1,14 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Use contact mechanism from address
+
+Version 6.4.0 - 2022-05-02
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+--------------------------
+* Initial release
diff --git a/modules/stock_package_shipping_mygls/COPYRIGHT b/modules/stock_package_shipping_mygls/COPYRIGHT
new file mode 100644
index 0000000000..852c531661
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2021-2022 B2CK
+Copyright (C) 2021-2022 Cédric Krier
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_package_shipping_mygls/LICENSE b/modules/stock_package_shipping_mygls/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_package_shipping_mygls/MANIFEST.in b/modules/stock_package_shipping_mygls/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_package_shipping_mygls/README.rst b/modules/stock_package_shipping_mygls/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_package_shipping_mygls/__init__.py b/modules/stock_package_shipping_mygls/__init__.py
new file mode 100644
index 0000000000..b0b9a91c04
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/__init__.py
@@ -0,0 +1,22 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import carrier, stock
+
+__all__ = ['register']
+
+
+def register():
+ Pool.register(
+ carrier.CredentialMyGLS,
+ carrier.Carrier,
+ stock.Package,
+ stock.ShipmentOut,
+ stock.ShipmentInReturn,
+ module='stock_package_shipping_mygls', type_='model')
+ Pool.register(
+ stock.ShipmentCreateShipping,
+ stock.ShipmentCreateShippingMyGLS,
+ module='stock_package_shipping_mygls', type_='wizard')
diff --git a/modules/stock_package_shipping_mygls/api.py b/modules/stock_package_shipping_mygls/api.py
new file mode 100644
index 0000000000..33e14ef77c
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/api.py
@@ -0,0 +1,33 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import hashlib
+
+from zeep import Client
+from zeep.transports import Transport
+
+from trytond.config import config
+
+URLS = {
+ 'testing': 'https://api.test.mygls.%(country)s/%(service)s.svc?singleWsdl',
+ 'production': 'https://api.mygls.%(country)s/%(service)s.svc?singleWsdl',
+ }
+TIMEOUT = config.get(
+ 'stock_package_shipping_mygls', 'requests_timeout', default=300)
+
+
+def get_client(credential, service):
+ url = URLS[credential.server] % {
+ 'country': credential.country,
+ 'service': service,
+ }
+ return Client(url, transport=Transport(operation_timeout=TIMEOUT))
+
+
+def get_request(credential, name, **kwargs):
+ return {
+ name: {
+ 'Username': credential.username,
+ 'Password': hashlib.sha512(credential.password.encode()).digest(),
+ **kwargs,
+ },
+ }
diff --git a/modules/stock_package_shipping_mygls/carrier.py b/modules/stock_package_shipping_mygls/carrier.py
new file mode 100644
index 0000000000..3b0d680cfe
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/carrier.py
@@ -0,0 +1,110 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.model import (
+ MatchMixin, ModelSQL, ModelView, fields, sequence_ordered)
+from trytond.pool import PoolMeta
+from trytond.pyson import Eval, If
+
+
+class CredentialMyGLS(sequence_ordered(), ModelSQL, ModelView, MatchMixin):
+ "MyGLS Credential"
+ __name__ = 'carrier.credential.mygls'
+
+ company = fields.Many2One('company.company', "Company")
+ server = fields.Selection([
+ ('testing', "Testing"),
+ ('production', "Production"),
+ ], "Server", required=True)
+ country = fields.Selection([
+ ('hr', "Croatia"),
+ ('cz', "Czechia"),
+ ('hu', "Hungary"),
+ ('ro', "Romania"),
+ ('si', "Slovenia"),
+ ('sk', "Slovakia"),
+ ], "Country", required=True)
+ username = fields.Char("Username", required=True, strip=False)
+ password = fields.Char("Password", required=True, strip=False)
+ client_number = fields.Integer("Client Number", required=True)
+
+ @classmethod
+ def default_server(cls):
+ return 'testing'
+
+
+class Carrier(metaclass=PoolMeta):
+ __name__ = 'carrier'
+
+ mygls_type_of_printer = fields.Selection([
+ (None, ''),
+ ('A4_2x2', "A4 2x2"),
+ ('A4_4x1', "A4 4x1"),
+ ('Connect', "Connect"),
+ ('Thermo', "Thermo"),
+ ], "Type of Printer", sort=False, translate=False,
+ states={
+ 'invisible': Eval('shipping_service') != 'mygls',
+ })
+ mygls_print_position = fields.Integer(
+ "Print Position",
+ domain=[
+ If(Eval('mygls_type_of_printer') == 'A4_2x2',
+ ('mygls_print_position', 'in', [1, 2, 3, 4]),
+ ('mygls_print_position', '=', None)),
+ ],
+ states={
+ 'required': Eval('mygls_type_of_printer') == 'A4_2x2',
+ 'invisible': (
+ (Eval('mygls_type_of_printer') != 'A4_2x2')
+ | (Eval('shipping_service') != 'mygls')),
+ })
+ mygls_services = fields.MultiSelection([
+ ('24h', "Service guaranteed delivery shipment in 24 Hours"),
+ ('AOS', "Addressee Only Service"),
+ ('CS1', "Contact Service"),
+ ('FDS', "Flexible Delivery Service"),
+ ('FSS', "Flexible delivery Sms Service"),
+ ('PRS', "Pick & Return Services"),
+ ('PSS', "Pick & Ship Service"),
+ ('SAT', "Saturday service"),
+ ('SBS', "Stand By Service"),
+ ('SM1', "SMS service"),
+ ('SM2', "SMS pre-advice"),
+ ('T09', "Express service (T09)"),
+ ('T10', "Express service (T10)"),
+ ('T12', "Express service (T12)"),
+ ('TGS', "Think Green Service"),
+ ('XS', "Exchange Service"),
+ ], "Services",
+ states={
+ 'invisible': Eval('shipping_service') != 'mygls',
+ })
+
+ mygls_sms = fields.Char(
+ "SMS", translate=True,
+ states={
+ 'invisible': Eval('shipping_service') != 'mygls',
+ 'required': Eval('mygls_services', []).contains('SM1'),
+ },
+ help="Variables that can be used in the text of the SMS:\n"
+ "ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#")
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls.shipping_service.selection.append(('mygls', "MyGLS"))
+
+ @classmethod
+ def view_attributes(cls):
+ return super(Carrier, cls).view_attributes() + [
+ ("/form/separator[@id='mygls']", 'states', {
+ 'invisible': Eval('shipping_service') != 'mygls',
+ }),
+ ]
+
+ @property
+ def shipping_label_mimetype(self):
+ mimetype = super().shipping_label_mimetype
+ if self.shipping_service == 'mygls':
+ mimetype = 'application/pdf'
+ return mimetype
diff --git a/modules/stock_package_shipping_mygls/carrier.xml b/modules/stock_package_shipping_mygls/carrier.xml
new file mode 100644
index 0000000000..10a65d292e
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/carrier.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+ carrier.credential.mygls
+ form
+ credential_form
+
+
+ carrier.credential.mygls
+ tree
+ credential_list
+
+
+
+ MyGLS Credentials
+ carrier.credential.mygls
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ carrier
+
+ carrier_form
+
+
+
diff --git a/modules/stock_package_shipping_mygls/doc/conf.py b/modules/stock_package_shipping_mygls/doc/conf.py
new file mode 100644
index 0000000000..8513b72dd2
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/doc/conf.py
@@ -0,0 +1,61 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+modules_url = 'https://docs.tryton.org/projects/modules-{module}/en/{series}/'
+trytond_url = 'https://docs.tryton.org/projects/server/en/{series}/'
+
+
+def get_info():
+ import configparser
+ import os
+ import subprocess
+ import sys
+
+ module_dir = os.path.dirname(os.path.dirname(__file__))
+
+ config = configparser.ConfigParser()
+ config.read_file(open(os.path.join(module_dir, 'tryton.cfg')))
+ info = dict(config.items('tryton'))
+
+ result = subprocess.run(
+ [sys.executable, 'setup.py', '--name'],
+ stdout=subprocess.PIPE, check=True, cwd=module_dir)
+ info['name'] = result.stdout.decode('utf-8').strip()
+
+ result = subprocess.run(
+ [sys.executable, 'setup.py', '--version'],
+ stdout=subprocess.PIPE, check=True, cwd=module_dir)
+ version = result.stdout.decode('utf-8').strip()
+ if 'dev' in version:
+ info['series'] = 'latest'
+ else:
+ info['series'] = '.'.join(version.split('.', 2)[:2])
+
+ for key in {'depends', 'extras_depend'}:
+ info[key] = info.get(key, '').strip().splitlines()
+ info['modules'] = set(info['depends'] + info['extras_depend'])
+ info['modules'] -= {'ir', 'res'}
+
+ return info
+
+
+info = get_info()
+
+master_doc = 'index'
+project = info['name']
+release = version = info['series']
+default_role = 'ref'
+highlight_language = 'none'
+extensions = [
+ 'sphinx.ext.intersphinx',
+ ]
+intersphinx_mapping = {
+ 'trytond': (trytond_url.format(series=version), None),
+ }
+intersphinx_mapping.update({
+ m: (modules_url.format(
+ module=m.replace('_', '-'), series=version), None)
+ for m in info['modules']
+ })
+
+del get_info, info, modules_url, trytond_url
diff --git a/modules/stock_package_shipping_mygls/doc/design.rst b/modules/stock_package_shipping_mygls/doc/design.rst
new file mode 100644
index 0000000000..2d9d077007
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/doc/design.rst
@@ -0,0 +1,36 @@
+******
+Design
+******
+
+The *Stock Package Shipping MyGLS Module* introduces or extends the following
+concepts.
+
+.. _model-carrier.credential.mygls:
+
+MyGLS Credential
+================
+
+This is used to store the credentials needed to connect to the MyGLS API.
+
+.. seealso::
+
+ The credentials can be accessed from the main menu item:
+
+ |Carrier --> Configuration --> MyGLS Credentials|__
+
+ .. |Carrier --> Configuration --> MyGLS Credentials| replace:: :menuselection:`Carrier --> Configuration --> MyGLS Credentials`
+ __ https://demo.tryton.org/model/carrier.credential.mygls
+
+.. _model-carrier:
+
+Carrier
+=======
+
+When the *Stock Package Shipping MyGLS Module* is activated, carriers gain some
+extra properties.
+These include a new shipping server "MyGLS", printer configuration and services.
+
+.. seealso::
+
+ The :doc:`Carrier ` concept is introduced by the
+ :doc:`Carrier Module `.
diff --git a/modules/stock_package_shipping_mygls/doc/index.rst b/modules/stock_package_shipping_mygls/doc/index.rst
new file mode 100644
index 0000000000..0e97424206
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/doc/index.rst
@@ -0,0 +1,12 @@
+###################################
+Stock Package Shipping MyGLS Module
+###################################
+
+The *Stock Package Shipping MyGLS Module* allows package labels to be generated
+for shipments using `MyGLS `_ webservices.
+
+.. toctree::
+ :maxdepth: 2
+
+ design
+ releases
diff --git a/modules/stock_package_shipping_mygls/doc/releases.rst b/modules/stock_package_shipping_mygls/doc/releases.rst
new file mode 100644
index 0000000000..21b13c4745
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/doc/releases.rst
@@ -0,0 +1,7 @@
+.. _releases-index:
+
+=============
+Release notes
+=============
+
+.. include:: ../CHANGELOG
diff --git a/modules/stock_package_shipping_mygls/exceptions.py b/modules/stock_package_shipping_mygls/exceptions.py
new file mode 100644
index 0000000000..5da7ef4d7a
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/exceptions.py
@@ -0,0 +1,7 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.exceptions import UserError
+
+
+class MyGLSError(UserError):
+ pass
diff --git a/modules/stock_package_shipping_mygls/locale/bg.po b/modules/stock_package_shipping_mygls/locale/bg.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/bg.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/ca.po b/modules/stock_package_shipping_mygls/locale/ca.po
new file mode 100644
index 0000000000..90ef9d49a7
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/ca.po
@@ -0,0 +1,243 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr "Posició d’impressió"
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr "Serveis"
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr "SMS"
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr "Tipus d’impressora"
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr "Número de client"
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr "País"
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr "Contrasenya"
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr "Servidor"
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr "Nom d'usuari"
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr "ID"
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+"Variables que es poden utilitzar al text de l'SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr "Credencial MyGLS"
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr "Crear enviaments MyGLS pels paquets"
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr "Credencials MyGLS"
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+"Per validar l'albarà \"%(shipment)s\", heu d'afegir un correu electrònic a "
+"l'adreça \"%(address)s\"."
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+"Per validar l'albarà \"%(shipment)s\", heu d'afegir un número de mòbil a "
+"l'adreça \"%(address)s\"."
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"La crida de l'API MyGLS ha fallat amb el següent missatge d'error:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+"Per validar l'albarà \"%(shipment)s\", heu d'afegir un número de telèfon o "
+"mòbil a l'adreça \"%(address)s\"."
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+"No podeu crear una etiqueta d'enviament per l'albarà \"%(shipment)s\" perquè"
+" ja té un número de referència."
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+"Per validar l'albarà \"%(shipment)s\", heu d'establir un codi de país a "
+"l'adreça de destinació."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+"Per validar l'albarà \"%(shipment)s\", heu d'establir un codi de país a "
+"l'adreça del magatzem \"%(warehouse)s\"."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+"Per validar l'albarà \"%(shipment)s\" heu d'establir una adreça al magatzem "
+"\"%(warehouse)s\"."
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr "Credencials MyGLS"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr "Servei només destinatari"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr "Servei de contacte"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr "Servei d’intercanvi"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr "Servei exprés (T09)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr "Servei exprés (T10)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr "Servei exprés (T12)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr "Servei de lliurament flexible"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr "Servei SMS de lliurament flexible"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr "Serveis de recollida i devolució"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr "Servei de recollida i enviament"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr "Preavís per SMS"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr "Servei SMS"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr "Servei de dissabte"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr "Servei de lliurament garantit en 24 hores"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr "Servei de guàrdia"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr "Servei de pensa en verd"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr "MyGLS"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr "Croàcia"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr "Txèquia"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr "Hongria"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr "Romania"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr "Eslovàquia"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr "Eslovènia"
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr "Producció"
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr "Proves"
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr "Informació de les credencials"
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr "MyGLS"
diff --git a/modules/stock_package_shipping_mygls/locale/cs.po b/modules/stock_package_shipping_mygls/locale/cs.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/cs.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/de.po b/modules/stock_package_shipping_mygls/locale/de.po
new file mode 100644
index 0000000000..4edfcd0f5e
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/de.po
@@ -0,0 +1,244 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr "Druckposition"
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr "Dienstleistungen"
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr "SMS"
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr "Druckertyp"
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr "Kundennummer"
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr "Unternehmen"
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr "Land"
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr "Passwort"
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr "Server"
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr "Benutzername"
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr "ID"
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+"Variablen, die im Text der SMS verwendet werden können:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr "MyGLS Anmeldedaten"
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr "MyGLS Versandauftrag für Pakete erstellen"
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr "MyGLS Anmeldedaten"
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+"Damit die Lieferung \"%(shipment)s\" validiert werden kann muss eine E-Mail-"
+"Adresse für Adresse \"%(address)s\" erfasst werden."
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+"Damit die Lieferung \"%(shipment)s\" validiert werden kann, muss eine "
+"Mobilnummer für die Adresse \"%(address)s\" erfasst werden."
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"Beim Aufruf der MyGLS API ist folgender Fehler aufgetreten:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+"Damit die Lieferung \"%(shipment)s\" validiert werden kann muss eine "
+"Telefonnummer oder eine Mobilnummer für die Adresse \"%(address)s\" erfasst "
+"werden."
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+"Es kann kein Versandetikett für die Lieferung \"%(shipment)s\" erstellt "
+"werden, weil bereits eine Referenznummer vorhanden ist."
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+"Damit die Lieferung \"%(shipment)s\" validiert werden kann, muss ein Land "
+"auf der Empfängeradresse erfasst werden."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+"Damit die Lieferung \"%(shipment)s\" validiert werden kann, muss ein Land "
+"für Adresse des Logistikstandorts \"%(warehouse)s\" erfasst werden."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+"Damit die Lieferung \"%(shipment)s\" validiert werden kann, muss eine "
+"Adresse für den Logistikstandort \"%(warehouse)s\" erfasst werden."
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr "MyGLS Anmeldedaten"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr "Zusatzleistung Eigenhändig"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr "Zusatzleistung Anruf"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr "Austausch"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr "Express (T09)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr "Express (T10)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr "Express (T12)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr "FlexDeliveryService"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr "FlexDeliverySMSService"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr "Pick&ReturnService"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr "Pick&ShipService"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr "SMS Vorankündigung"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr "Zusatzleistung SMS"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr "Samstagszustellung"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr "Garantierte Zustellung innerhalb von 24 Stunden"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr "Abholung durch den Empfänger"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr "ThinkGreenService"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr "MyGLS"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr "Kroatien"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr "Tschechien"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr "Ungarn"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr "Rumänien"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr "Slowakei"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr "Slowenien"
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr "Produktivumgebung"
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr "Testumgebung"
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr "Benutzeranmeldeinformationen"
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr "MyGLS"
diff --git a/modules/stock_package_shipping_mygls/locale/es.po b/modules/stock_package_shipping_mygls/locale/es.po
new file mode 100644
index 0000000000..5a6d82bfef
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/es.po
@@ -0,0 +1,243 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr "Posición de impresión"
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr "Servicios"
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr "SMS"
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr "Tipo de impresora"
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr "Número de cliente"
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr "País"
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr "Contraseña"
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr "Servidor"
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr "Nombre de usuario"
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr "ID"
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+"Variables que se pueden utilizar en el texto del SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr "Credencial MyGLS"
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr "Crear envíos MyGLS para paquetes"
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr "Credenciales MyGLS"
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+"Para validar el albarán \"%(shipment)s\" debe agregar un correo electrónico "
+"a la dirección \"%(address)s\"."
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+"Para validar el albarán \"%(shipment)s\" debe agregar un número de móvil a "
+"la dirección \"%(address)s\"."
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"La llamada de la API de MyGLS ha fallado con el siguiente mensaje de error:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+"Para validar el albarán \"%(shipment)s\" debe agregar un número de teléfono "
+"o móvil la dirección \"%(address)s\"."
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+"No puedes crear una etiqueta de envío para el albarán \"%(shipment)s\" "
+"porque ya tiene un número de referencia."
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+"Para validar el albarán \"%(shipment)s\" debe establecer un código de país "
+"en la dirección de destino."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+"Para validar el albarán \"%(shipment)s\" debe establecer un código de país "
+"en la dirección del almacén \"%(warehouse)s\"."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+"Para validar el albarán \"%(shipment)s\" debe establecer una dirección en el"
+" almacén \"%(warehouse)s\"."
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr "Credenciales MyGLS"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr "Servicio solo destinatario"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr "Servicio de contacto"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr "Servicio de intercambio"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr "Servicio exprés (T09)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr "Servicio exprés (T10)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr "Servicio exprés (T12)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr "Servicio de entrega flexible"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr "Servicio SMS de entrega flexible"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr "Servicios de recogida y devolución"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr "Servicio de recogida y envío"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr "Preaviso por SMS"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr "Servicio SMS"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr "Servicio de sábado"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr "Servicio de entrega garantizada en 24 horas"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr "Servicio de guardia"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr "Servicio de piensa en verde"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr "MyGLS"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr "Croacia"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr "Chequia"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr "Hungría"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr "Rumanía"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr "Eslovaquia"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr "Eslovenia"
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr "Producción"
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr "Pruebas"
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr "Información de las credenciales"
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr "MyGLS"
diff --git a/modules/stock_package_shipping_mygls/locale/es_419.po b/modules/stock_package_shipping_mygls/locale/es_419.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/es_419.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/et.po b/modules/stock_package_shipping_mygls/locale/et.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/et.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/fa.po b/modules/stock_package_shipping_mygls/locale/fa.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/fa.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/fi.po b/modules/stock_package_shipping_mygls/locale/fi.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/fi.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/fr.po b/modules/stock_package_shipping_mygls/locale/fr.po
new file mode 100644
index 0000000000..3939379e97
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/fr.po
@@ -0,0 +1,243 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr "Position d'impression"
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr "Services"
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr "SMS"
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr "Type d'imprimante"
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr "Numéro client"
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr "Société"
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr "Pays"
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr "Mot de passe"
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr "Serveur"
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr "Nom d'utilisateur"
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr "ID"
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+"Variables utilisables dans le texte du SMS :\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr "Identifiant MyGLS"
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr "Créer la livraison MyGLS pour les emballages"
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr "Identifiants MyGLS"
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+"Pour valider l'expédition « %(shipment)s », vous devez ajouter un e-mail à "
+"l'adresse « %(address)s »."
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+"Pour valider l'expédition « %(shipment)s », vous devez ajouter un numéro de "
+"téléphone mobile pour l'adresse « %(address)s »."
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"L'appel de l'API MyGLS a échoué avec le message d'erreur suivant :\n"
+"%(messages)s"
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+"Pour valider l'expédition « %(shipment)s », vous devez ajouter un numéro de "
+"téléphone ou mobile à l'adresse « %(address)s »."
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+"Vous ne pouvez pas créer d'étiquette de livraison pour l'expédition "
+"« %(shipment)s » car elle a déjà un numéro de référence."
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+"Pour valider l'expédition « %(shipment)s », vous devez remplir un code pays "
+"à l'adresse de destination."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+"Pour valider l'expédition « %(shipment)s », vous devez remplir un code pays "
+"à l'adresse de l'entrepôt « %(warehouse)s »."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+"Pour validé l'expédition « %(shipment)s », vous devez définir une adresse "
+"pour l'entrepôt « %(warehouse)s »."
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr "Identifiants MyGLS"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr "Service au destinataire uniquement"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr "Service de contact"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr "Service d'échange"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr "Service express (T09)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr "Service express (T10)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr "Service express (T12)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr "Service de livraison flexible"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr "Service de livraison Sms flexible"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr "Services de prélèvement et de retour"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr "Service de prélèvement et d'expédition"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr "Pré-avis SMS"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr "Service SMS"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr "Service du samedi"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr "Service de livraison garantie expédition en 24 heures"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr "Service d'attente"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr "Service penser vert"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr "MyGLS"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr "Croatie"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr "Tchéquie"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr "Hongrie"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr "Roumanie"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr "Slovaquie"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr "Slovénie"
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr "Essai"
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr "Informations d'identification"
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr "MyGLS"
diff --git a/modules/stock_package_shipping_mygls/locale/hu.po b/modules/stock_package_shipping_mygls/locale/hu.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/hu.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/id.po b/modules/stock_package_shipping_mygls/locale/id.po
new file mode 100644
index 0000000000..f895d195f1
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/id.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr "Perusahaan"
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr "Produksi"
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr "Testing"
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/it.po b/modules/stock_package_shipping_mygls/locale/it.po
new file mode 100644
index 0000000000..2a96044316
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/it.po
@@ -0,0 +1,227 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+"Non puoi creare un'etichetta di spedizione per la spedizione "
+"\"%(shipment)s\" perché ha già un numero di riferimento."
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/lo.po b/modules/stock_package_shipping_mygls/locale/lo.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/lo.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/lt.po b/modules/stock_package_shipping_mygls/locale/lt.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/lt.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/nl.po b/modules/stock_package_shipping_mygls/locale/nl.po
new file mode 100644
index 0000000000..1031e6ade8
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/nl.po
@@ -0,0 +1,243 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr "Afdrukpositie"
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr "Diensten"
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr "SMS"
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr "Type printer"
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr "Klantnummer"
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr "Bedrijf"
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr "Land"
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr "Wachtwoord"
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr "Server"
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr "Gebruikersnaam"
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr "ID"
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+"Variabelen die gebruikt kunnen worden in de tekst van de SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr "MijnGLS-referentie"
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr "Creëer MyGLS-verzending voor pakketten"
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr "MyGLS-referentie"
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+"Om zending \"%(shipment)s\" te valideren, moet u een e-mailadres toevoegen "
+"voor adres \"%(address)s\"."
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+"Om zending \"%(shipment)s\" te valideren, moet u een mobiel nummer toevoegen"
+" aan adres\"%(address)s\"."
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"Bij het aanroepen van de MyGLS API is de volgende fout opgetreden:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+"Om zending \"%(shipment)s\"\" te valideren, moet u een telefoon- of mobiel "
+"nummer toevoegen aan adres \"%(address)s\"."
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+"U kunt geen verzendlabel maken voor verzending \"%(shipment)s\", omdat deze "
+"al een referentienummer heeft."
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+"Om verzending \"%(shipment)s\" te valideren, moet u een landcode instellen "
+"op het bestemmingsadres."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+"Om verzending \"%(shipment)s\" te valideren, moet u een landcode instellen "
+"op het adres van het magazijn \"%(warehouse)s\"."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+"Om zending \"%(shipment)s\" te valideren, moet u een adres voor magazijn "
+"\"%(warehouse)s\" instellen."
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr "MijnGLS-referentie"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr "Service alleen voor geadresseerde"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr "Neem contact op met de dienst"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr "Wissel dienst"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr "Expresdienst (T09)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr "Expresdienst (T10)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr "Expresdienst (T12)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr "Flexibele bezorgservice"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr "Flexibele levering Sms-service"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr "Pick & Return-services"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr "Ophaal- en verzendservice"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr "SMS pre-advies"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr "SMS-dienst"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr "Zaterdagdienst"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr "Service gegarandeerde levering verzending in 24 uur"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr "Stand-by-service"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr "Milieuvriendelijke Dienst"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr "MyGLS"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr "Kroatië"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr "Tsjechië"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr "Hongarije"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr "Roemenië"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr "Slowakije"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr "Slovenië"
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr "Productie"
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr "Testen"
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr "Referentiegegevens"
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr "MyGLS"
diff --git a/modules/stock_package_shipping_mygls/locale/pl.po b/modules/stock_package_shipping_mygls/locale/pl.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/pl.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/pt.po b/modules/stock_package_shipping_mygls/locale/pt.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/pt.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/ro.po b/modules/stock_package_shipping_mygls/locale/ro.po
new file mode 100644
index 0000000000..0222cdc8f6
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/ro.po
@@ -0,0 +1,246 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr "Poziţia Printare"
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr "Servicii"
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr "SMS"
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr "Tip de Imprimanta"
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr "Număr Client"
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr "Companie"
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr "Țară"
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr "Parola"
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr "Server"
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr "Utilizator"
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr "ID"
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+"Variabile care pot fi utilizate în textul SMS-ului:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr "Credenţiale MyGLS"
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr "Creare Expediere MyGLS pentru Colete"
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr "Credenţiale MyGLS"
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+"Pentru a valida expedierea \"%(shipment)s\" trebuie să adăugaţi o adresă de "
+"e-mail la parte \"%(party)s\"."
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+"Pentru a valida expedierea \"%(shipment)s\" trebuie adăugat un număr de "
+"telefon mobil la parte \"%(party)s\"."
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"Interogarea API MyGLS a eşuat cu următorul mesaj:\n"
+"%(message)s"
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+"Pentru a valida expedierea \"%(shipment)s\"trebuie adăugat un număr de "
+"telefon mobil la parte \"%(party)s\"."
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+"Nu se poate crea o eticheta pentru expedierea \"%(shipment)s\" pentru că are"
+" deja un număr de referinţa."
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+"Pentru a valida expedierea \"%(shipment)s\" trebuie sa fie setat un cod de "
+"ţara la adresă al destinatarului."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+"Pentru a valida expedierea \"%(shipment)s\" trebuie sa fie setat un cod de "
+"ţara la adresa al depozitului \"%(warehouse)s\"."
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+"Pentru a valida expedierea \"%(shipment)s\" trebuie setata o adresa la "
+"depozit \"%(warehouse)s\"."
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr "Credenţiale MyGLS"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr "Serviciul Exclusiv Destinatarului"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr "Serviciul Contact"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr "Serviciul de Schimb"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr "Serviciul Expres (T9)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr "Serviciul Expres (T10)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr "Serviciul Expres (T12)"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr "Serviciul Livrare Flexibila"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr "Serviciul Livrare Flexibila cu SMS"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr "Serviciul Ridicare & Retur"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr "Serviciul Ridicare & Expediere"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr "Avertizare în prealabil prin SMS"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr "Serviciul SMS"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr "Serviciul Sămbata"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr "Serviciul cu garanţie livrării în 24 Ore"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr "Serviciul În Aşteptare"
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr "Serviciul Gândeşte Verde"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr "MyGLS"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr "Croaţia"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr "Cehia"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr "Ungaria"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr "România"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr "Slovacia"
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr "Slovenia"
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr "Producţie"
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr "Testare"
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr "Informaţii Credenţiale"
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr "MyGLS"
diff --git a/modules/stock_package_shipping_mygls/locale/ru.po b/modules/stock_package_shipping_mygls/locale/ru.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/ru.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/sl.po b/modules/stock_package_shipping_mygls/locale/sl.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/sl.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/tr.po b/modules/stock_package_shipping_mygls/locale/tr.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/tr.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/uk.po b/modules/stock_package_shipping_mygls/locale/uk.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/uk.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/locale/zh_CN.po b/modules/stock_package_shipping_mygls/locale/zh_CN.po
new file mode 100644
index 0000000000..578cf3e7b5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/locale/zh_CN.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,mygls_print_position:"
+msgid "Print Position"
+msgstr ""
+
+msgctxt "field:carrier,mygls_services:"
+msgid "Services"
+msgstr ""
+
+msgctxt "field:carrier,mygls_sms:"
+msgid "SMS"
+msgstr ""
+
+msgctxt "field:carrier,mygls_type_of_printer:"
+msgid "Type of Printer"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,client_number:"
+msgid "Client Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,country:"
+msgid "Country"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.mygls,username:"
+msgid "Username"
+msgstr ""
+
+msgctxt "field:stock.package,mygls_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "help:carrier,mygls_sms:"
+msgid ""
+"Variables that can be used in the text of the SMS:\n"
+"ParcelNr#, #COD#, #PickupDate#, #From_Name#, #ClientRef#"
+msgstr ""
+
+msgctxt "model:carrier.credential.mygls,name:"
+msgid "MyGLS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_mygls_wizard"
+msgid "Create MyGLS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_email_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add an email for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a mobile number for "
+"address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_mygls_api_error"
+msgid ""
+"MyGLS API call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_mobile_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add a phone or mobile number "
+"for address \"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_to_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"destination address."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_country_code_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set a country code to the "
+"address of warehouse \"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "MyGLS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Addressee Only Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Contact Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Exchange Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T09)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T10)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Express service (T12)"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible Delivery Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Flexible delivery Sms Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Return Services"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Pick & Ship Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS pre-advice"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "SMS service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Saturday service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Service guaranteed delivery shipment in 24 Hours"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Stand By Service"
+msgstr ""
+
+msgctxt "selection:carrier,mygls_services:"
+msgid "Think Green Service"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "MyGLS"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Croatia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Czechia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Hungary"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Romania"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovakia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,country:"
+msgid "Slovenia"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.mygls,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.mygls:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "MyGLS"
+msgstr ""
diff --git a/modules/stock_package_shipping_mygls/message.xml b/modules/stock_package_shipping_mygls/message.xml
new file mode 100644
index 0000000000..dae1288fb7
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/message.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+ To validate shipment "%(shipment)s" you must set an address on warehouse "%(warehouse)s".
+
+
+ To validate shipment "%(shipment)s" you must set a country code to the address of warehouse "%(warehouse)s".
+
+
+ To validate shipment "%(shipment)s" you must set a country code to the destination address.
+
+
+ To validate shipment "%(shipment)s" you must add a phone or mobile number for address "%(address)s".
+
+
+ To validate shipment "%(shipment)s" you must add an email for address "%(address)s".
+
+
+ To validate shipment "%(shipment)s" you must add a mobile number for address "%(address)s".
+
+
+ You cannot create a shipping label for shipment "%(shipment)s" because it already has a reference number.
+
+
+ MyGLS API call failed with the following error message:
+%(message)s
+
+
+
diff --git a/modules/stock_package_shipping_mygls/setup.py b/modules/stock_package_shipping_mygls/setup.py
new file mode 100755
index 0000000000..022d45d3fa
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/setup.py
@@ -0,0 +1,162 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ content = io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+ content = re.sub(
+ r'(?m)^\.\. toctree::\r?\n((^$|^\s.*$)\r?\n)*', '', content)
+ return content
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_package_shipping_mygls'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+requires = ['zeep', 'PyPDF2']
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [
+ get_require_version('proteus'),
+ get_require_version('trytond_sale'),
+ get_require_version('trytond_sale_shipment_cost'),
+ ]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version)
+ )
+
+setup(name=name,
+ version=version,
+ description='MyGLS connector for the Tryton application platform',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": (
+ 'https://docs.tryton.org/projects/'
+ 'modules-stock-package-shipping-mygls'),
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": (
+ 'https://hg.tryton.org/modules/stock_package_shipping_mygls'),
+ },
+ keywords='tryton stock package shipping gls mygls',
+ package_dir={'trytond.modules.stock_package_shipping_mygls': '.'},
+ packages=(
+ ['trytond.modules.stock_package_shipping_mygls']
+ + ['trytond.modules.stock_package_shipping_mygls.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_package_shipping_mygls': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_package_shipping_mygls = trytond.modules.stock_package_shipping_mygls
+ """, # noqa: E501
+ )
diff --git a/modules/stock_package_shipping_mygls/stock.py b/modules/stock_package_shipping_mygls/stock.py
new file mode 100644
index 0000000000..2c0692bbc3
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/stock.py
@@ -0,0 +1,273 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from io import BytesIO
+from itertools import zip_longest
+
+from PyPDF2 import PdfFileReader, PdfFileWriter
+
+from trytond.i18n import gettext
+from trytond.model import fields
+from trytond.model.exceptions import AccessError
+from trytond.modules.stock_package_shipping.exceptions import (
+ PackingValidationError)
+from trytond.pool import Pool, PoolMeta
+from trytond.transaction import Transaction
+from trytond.wizard import StateAction, StateTransition, Wizard
+
+from .api import get_client, get_request
+from .exceptions import MyGLSError
+
+
+class Package(metaclass=PoolMeta):
+ __name__ = 'stock.package'
+
+ mygls_shipping_id = fields.Integer("ID", readonly=True)
+
+ @classmethod
+ def copy(cls, packages, default=None):
+ default = {} if default is None else default.copy()
+ default.setdefault('mygls_shipping_id')
+ return super().copy(packages, default=default)
+
+
+class ShippingMyGLSMixin:
+ __slots__ = ()
+
+ def get_mygls_credential(self):
+ pool = Pool()
+ Credential = pool.get('carrier.credential.mygls')
+
+ pattern = self._get_mygls_credential_pattern()
+ for credential in Credential.search([]):
+ if credential.match(pattern):
+ return credential
+
+ def _get_mygls_credential_pattern(self):
+ return {
+ 'company': self.company.id,
+ 'country': self.shipping_warehouse.address.country.code.lower(),
+ }
+
+ def validate_packing_mygls(self, usage=None):
+ warehouse = self.shipping_warehouse
+ if not warehouse.address:
+ raise PackingValidationError(
+ gettext('stock_package_shipping_mygls'
+ '.msg_warehouse_address_required',
+ shipment=self.rec_name,
+ warehouse=warehouse.rec_name))
+ if not warehouse.address.country or not warehouse.address.country.code:
+ raise PackingValidationError(
+ gettext('stock_package_shipping_mygls'
+ '.msg_warehouse_address_country_code_required',
+ shipment=self.rec_name,
+ warehouse=warehouse.rec_name))
+ shipping_to_address = self.shipping_to_address
+ if (not shipping_to_address.country
+ or not shipping_to_address.country.code):
+ raise PackingValidationError(
+ gettext('stock_package_shipping_mygls'
+ '.msg_shipping_to_address_country_code_required',
+ shipping=self.rec_name))
+ if (self.carrier.mygls_services
+ and 'CS1' in self.carrier.mygls_services):
+ if not shipping_to_address.contact_mechanism_get(
+ {'phone', 'mobile'}, usage=usage):
+ raise PackingValidationError(
+ gettext('stock_package_shipping_mygls'
+ '.msg_phone_mobile_required',
+ shipment=self.rec_name,
+ address=shipping_to_address.rec_name))
+ if (self.carrier.mygls_services
+ and 'FDS' in self.carrier.mygls_services):
+ if not shipping_to_address.contact_mechanism_get(
+ 'email', usage=usage):
+ raise PackingValidationError(
+ gettext('stock_package_shipping_mygls'
+ '.msg_email_required',
+ shipment=self.rec_name,
+ address=shipping_to_address.rec_name))
+ if (self.carrier.mygls_services
+ and ('FSS' in self.carrier.mygls_services
+ or 'SM1' in self.carrier.mygls_services
+ or 'SM2' in self.carrier.mygls_services)):
+ if not shipping_to_address.contact_mechanism_get(
+ 'mobile', usage=usage):
+ raise PackingValidationError(
+ gettext('stock_package_shipping_mygls'
+ '.msg_mobile_required',
+ shipment=self.rec_name,
+ address=shipping_to_address.rec_name))
+
+
+class ShipmentOut(ShippingMyGLSMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out'
+
+
+class ShipmentInReturn(ShippingMyGLSMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in.return'
+
+
+class ShipmentCreateShipping(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.create_shipping'
+
+ mygls = StateAction(
+ 'stock_package_shipping_mygls.act_create_shipping_mygls_wizard')
+
+ def transition_start(self):
+ next_state = super().transition_start()
+ if self.record.carrier.shipping_service == 'mygls':
+ next_state = 'mygls'
+ return next_state
+
+ def do_mygls(self, action):
+ ctx = Transaction().context
+ return action, {
+ 'model': ctx['active_model'],
+ 'id': ctx['active_id'],
+ 'ids': [ctx['active_id']],
+ }
+
+
+class ShipmentCreateShippingMyGLS(Wizard):
+ "Create MyGLS Shipping"
+ __name__ = 'stock.shipment.create_shipping.mygls'
+
+ start = StateTransition()
+
+ def transition_start(self):
+ pool = Pool()
+ Package = pool.get('stock.package')
+
+ shipment = self.record
+ if shipment.reference:
+ raise AccessError(
+ gettext('stock_package_shipping_mygls'
+ '.msg_shipment_has_reference_number',
+ shipment=shipment.rec_name))
+
+ credential = shipment.get_mygls_credential()
+ client = get_client(credential, 'ParcelService')
+ carrier = shipment.carrier
+ packages = shipment.root_packages
+
+ parcel = self.get_parcel(shipment, packages, credential)
+
+ response = client.service.PrintLabels(**get_request(
+ credential, 'printLabelsRequest',
+ ParcelList=[{'Parcel': parcel}],
+ TypeOfPrinter=carrier.mygls_type_of_printer,
+ PrintPosition=carrier.mygls_print_position))
+
+ if response.PrintLabelsErrorList:
+ message = "\n".join(
+ e.ErrorDescription
+ for e in response.PrintLabelsErrorList.ErrorInfo)
+ raise MyGLSError(
+ gettext('stock_package_shipping_mygls.msg_mygls_api_error',
+ message=message))
+
+ labels = []
+ reader = PdfFileReader(BytesIO(response.Labels))
+ for i in range(reader.getNumPages()):
+ pdf = PdfFileWriter()
+ label = BytesIO()
+ pdf.addPage(reader.getPage(i))
+ pdf.write(label)
+ if carrier.mygls_type_of_printer in {'A4_2x2', 'A4_4x1'}:
+ if carrier.mygls_type_of_printer == 'A4_2x2':
+ gap = carrier.mygls_print_position - 1
+ else:
+ gap = 0
+ max_label = ((i + 1) * 4) - gap
+ n = 4
+ if i == 0:
+ n -= gap
+ if max_label > len(packages):
+ n -= max_label - len(packages)
+ labels.extend([label] * n)
+ else:
+ labels.append(label)
+ labels_info = response.PrintLabelsInfoList.PrintLabelsInfo
+
+ for package, label, info in zip_longest(
+ packages, labels, labels_info):
+ package.mygls_shipping_id = info.ParcelId
+ package.shipping_label = fields.Binary.cast(label.getvalue())
+ package.shipping_label_mimetype = carrier.shipping_label_mimetype
+ package.shipping_reference = info.ParcelNumber
+ if not shipment.reference:
+ shipment.reference = info.ParcelNumber
+ Package.save(packages)
+ shipment.save()
+
+ return 'end'
+
+ def get_parcel(self, shipment, packages, credential):
+ services = []
+ if shipment.carrier.mygls_services:
+ for code in shipment.carrier.mygls_services:
+ services.append({'Service': self.get_service(code, shipment)})
+ return {
+ 'ClientNumber': credential.client_number,
+ 'ClientReference': shipment.number,
+ 'Count': len(packages),
+ 'Content': shipment.shipping_description,
+ 'PickupAddress': self.get_address(
+ shipment.company.party,
+ shipment.shipping_warehouse.address),
+ 'DeliveryAddress': self.get_address(
+ shipment.shipping_to,
+ shipment.shipping_to_address),
+ 'ServiceList': services,
+ }
+
+ def get_address(self, party, address, usage=None):
+ phone = address.contact_mechanism_get({'phone', 'mobile'}, usage=usage)
+ email = address.contact_mechanism_get('email', usage=usage)
+ return {
+ 'Name': address.party_full_name,
+ 'Street': ' '.join((address.street or '').splitlines()),
+ 'City': address.city,
+ 'ZipCode': address.postal_code,
+ 'CountryIsoCode': address.country.code,
+ 'ContactName': party.full_name,
+ 'ContactPhone': phone.value if phone else None,
+ 'ContactEmail': email.value if email else None,
+ }
+
+ def get_service(self, code, shipment, usage=None):
+ pool = Pool()
+ Carrier = pool.get('carrier')
+ service = {'Code': code}
+ shipping_to_address = shipment.shipping_to_address
+ if code == 'AOS':
+ service['AOSParameter'] = shipment.shipping_to.full_name,
+ elif code == 'CS1':
+ phone = shipping_to_address.contact_mechanism_get(
+ {'phone', 'mobile'}, usage=usage)
+ service['CS1Parameter'] = phone.value
+ elif code == 'FDS':
+ email = shipping_to_address.contact_mechanism_get(
+ 'email', usage=usage)
+ service['FDSParameter'] = email.value
+ elif code == 'FSS':
+ mobile = shipping_to_address.contact_mechanism_get(
+ 'mobile', usage=usage)
+ service['FSSParameter'] = mobile.value
+ elif code == 'SM1':
+ if shipment.shipping_to.lang:
+ lang_code = shipment.shipping_to.lang.code
+ else:
+ lang_code = None
+ with Transaction().set_context(language=lang_code):
+ carrier = Carrier(shipment.carrier.id)
+ mobile = shipping_to_address.contact_mechanism_get(
+ 'mobile', usage=usage)
+ service['SM1Parameter'] = '|'.join([
+ mobile.value, carrier.mygls_sms])
+ elif code == 'SM2':
+ mobile = shipping_to_address.contact_mechanism_get(
+ 'mobile', usage=usage)
+ service['SM1Parameter'] = mobile.value
+ return service
diff --git a/modules/stock_package_shipping_mygls/stock.xml b/modules/stock_package_shipping_mygls/stock.xml
new file mode 100644
index 0000000000..2328b92839
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/stock.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+ Create MyGLS Shipping for Packages
+ stock.shipment.create_shipping.mygls
+
+
+
diff --git a/modules/stock_package_shipping_mygls/tests/__init__.py b/modules/stock_package_shipping_mygls/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_package_shipping_mygls/tests/scenario_stock_package_shipping_mygls.rst b/modules/stock_package_shipping_mygls/tests/scenario_stock_package_shipping_mygls.rst
new file mode 100644
index 0000000000..7c64c25e3a
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/tests/scenario_stock_package_shipping_mygls.rst
@@ -0,0 +1,206 @@
+=====================================
+Stock Package Shipping MyGLS Scenario
+=====================================
+
+Imports::
+
+ >>> import os
+ >>> from decimal import Decimal
+
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import (
+ ... create_company, get_company)
+ >>> from trytond.modules.account.tests.tools import (
+ ... create_fiscalyear, create_chart, get_accounts)
+ >>> from trytond.modules.account_invoice.tests.tools import (
+ ... set_fiscalyear_invoice_sequences)
+
+Activate modules::
+
+ >>> config = activate_modules(
+ ... ['stock_package_shipping_mygls', 'sale', 'sale_shipment_cost'])
+
+ >>> Address = Model.get('party.address')
+ >>> Carrier = Model.get('carrier')
+ >>> CarrierSelection = Model.get('carrier.selection')
+ >>> Country = Model.get('country.country')
+ >>> Credential = Model.get('carrier.credential.mygls')
+ >>> Inventory = Model.get('stock.inventory')
+ >>> Location = Model.get('stock.location')
+ >>> Party = Model.get('party.party')
+ >>> ProductCategory = Model.get('product.category')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> ProductUom = Model.get('product.uom')
+ >>> Sale = Model.get('sale.sale')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create fiscal year::
+
+ >>> fiscalyear = set_fiscalyear_invoice_sequences(
+ ... create_fiscalyear(company))
+ >>> fiscalyear.click('create_period')
+
+Create chart of accounts::
+
+ >>> _ = create_chart(company)
+ >>> accounts = get_accounts(company)
+
+Create countries::
+
+ >>> hungary= Country(code='HU', name="Hungary")
+ >>> hungary.save()
+
+Create parties::
+
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+ >>> customer_address = customer.addresses.new()
+ >>> customer_address.street = "Európa u., 2"
+ >>> customer_address.postal_code = "2351"
+ >>> customer_address.city = "Alsónémedi"
+ >>> customer_address.country = hungary
+ >>> customer_address.save()
+ >>> customer_phone = customer.contact_mechanisms.new()
+ >>> customer_phone.type = 'phone'
+ >>> customer_phone.value = "+36701234567"
+ >>> customer_phone.save()
+
+Set the warehouse address::
+
+ >>> warehouse, = Location.find([('type', '=', 'warehouse')])
+ >>> company_address = Address()
+ >>> company_address.party = company.party
+ >>> company_address.street = "Európa u., 2"
+ >>> company_address.postal_code = "2351"
+ >>> company_address.city = "Alsónémedi"
+ >>> company_address.country = hungary
+ >>> company_address.save()
+ >>> company_phone = company.party.contact_mechanisms.new()
+ >>> company_phone.type = 'phone'
+ >>> company_phone.value = "+36701234567"
+ >>> company_phone.save()
+ >>> warehouse.address = company_address
+ >>> warehouse.save()
+
+Create account category::
+
+ >>> account_category = ProductCategory(name="Account Category")
+ >>> account_category.accounting = True
+ >>> account_category.account_expense = accounts['expense']
+ >>> account_category.account_revenue = accounts['revenue']
+ >>> account_category.save()
+
+Create product::
+
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.salable = True
+ >>> template.list_price = Decimal('10')
+ >>> template.account_category = account_category
+ >>> template.save()
+ >>> product, = template.products
+
+Create an Inventory::
+
+ >>> storage, = Location.find([
+ ... ('code', '=', 'STO'),
+ ... ])
+ >>> inventory = Inventory()
+ >>> inventory.location = storage
+ >>> inventory_line = inventory.lines.new(product=product)
+ >>> inventory_line.quantity = 100.0
+ >>> inventory_line.expected_quantity = 0.0
+ >>> inventory.click('confirm')
+ >>> inventory.state
+ 'done'
+
+Create Package Type::
+
+ >>> PackageType = Model.get('stock.package.type')
+ >>> box = PackageType(name='Box')
+ >>> box.save()
+
+Create a MyGLS carrier::
+
+ >>> credential = Credential()
+ >>> credential.company = company
+ >>> credential.server = 'testing'
+ >>> credential.country = 'hu'
+ >>> credential.username = os.getenv('MYGLS_USERNAME')
+ >>> credential.password = os.getenv('MYGLS_PASSWORD')
+ >>> credential.client_number = int(os.getenv('MYGLS_CLIENT_NUMBER'))
+ >>> credential.save()
+
+ >>> template = ProductTemplate()
+ >>> template.name = "GLS"
+ >>> template.default_uom = unit
+ >>> template.type = 'service'
+ >>> template.salable = True
+ >>> template.list_price = Decimal(20)
+ >>> template.account_category = account_category
+ >>> template.save()
+ >>> carrier_product, = template.products
+
+ >>> gls = Party(name="GLS")
+ >>> gls.save()
+
+ >>> carrier = Carrier()
+ >>> carrier.party = gls
+ >>> carrier.carrier_product = carrier_product
+ >>> carrier.shipping_service = 'mygls'
+ >>> carrier.mygls_type_of_printer = 'A4_2x2'
+ >>> carrier.mygls_print_position = 3
+ >>> carrier.mygls_services = ['CS1', 'TGS']
+ >>> carrier.save()
+
+Create a sale and thus a shipment::
+
+ >>> sale = Sale()
+ >>> sale.party = customer
+ >>> sale.shipment_address = customer_address
+ >>> sale.invoice_method = 'order'
+ >>> sale.carrier = carrier
+ >>> sale_line = sale.lines.new()
+ >>> sale_line.product = product
+ >>> sale_line.quantity = 1.0
+ >>> sale_line = sale.lines.new()
+ >>> sale_line.product = product
+ >>> sale_line.quantity = 1.0
+ >>> sale.click('quote')
+ >>> sale.click('confirm')
+ >>> sale.click('process')
+
+Create the packages and ship the shipment::
+
+ >>> shipment, = sale.shipments
+ >>> shipment.click('assign_force')
+ >>> shipment.click('pick')
+ >>> pack = shipment.packages.new(type=box)
+ >>> pack_moves = pack.moves.find([])
+ >>> pack.moves.append(pack_moves[0])
+ >>> pack = shipment.packages.new(type=box)
+ >>> pack.moves.append(pack_moves[1])
+ >>> shipment.click('pack')
+
+ >>> create_shipping = Wizard('stock.shipment.create_shipping', [shipment])
+ >>> shipment.reload()
+ >>> bool(shipment.reference)
+ True
+ >>> pack, _ = shipment.root_packages
+ >>> pack.shipping_label is not None
+ True
+ >>> pack.shipping_label_mimetype
+ 'application/pdf'
+ >>> pack.mygls_shipping_id is not None
+ True
+ >>> bool(pack.shipping_reference)
+ True
diff --git a/modules/stock_package_shipping_mygls/tests/test_module.py b/modules/stock_package_shipping_mygls/tests/test_module.py
new file mode 100644
index 0000000000..9791bdea82
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/tests/test_module.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockPackageShippingMyglsTestCase(ModuleTestCase):
+ 'Test Stock Package Shipping Mygls module'
+ module = 'stock_package_shipping_mygls'
+
+
+del ModuleTestCase
diff --git a/modules/stock_package_shipping_mygls/tests/test_scenario.py b/modules/stock_package_shipping_mygls/tests/test_scenario.py
new file mode 100644
index 0000000000..31fa2fd652
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/tests/test_scenario.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import os
+
+from trytond.tests.test_tryton import load_doc_tests
+
+if (os.getenv('MYGLS_USERNAME')
+ and os.getenv('MYGLS_PASSWORD')
+ and os.getenv('MYGLS_CLIENT_NUMBER')):
+ def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_package_shipping_mygls/tox.ini b/modules/stock_package_shipping_mygls/tox.ini
new file mode 100644
index 0000000000..44a40ee2bc
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_package_shipping_mygls/* -m unittest discover -s tests
+ coverage report --include=./**/stock_package_shipping_mygls/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_package_shipping_mygls/tryton.cfg b/modules/stock_package_shipping_mygls/tryton.cfg
new file mode 100644
index 0000000000..a9e3aaa951
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/tryton.cfg
@@ -0,0 +1,12 @@
+[tryton]
+version=6.7.0
+depends:
+ carrier
+ ir
+ stock
+ stock_package
+ stock_package_shipping
+xml:
+ carrier.xml
+ stock.xml
+ message.xml
diff --git a/modules/stock_package_shipping_mygls/view/carrier_form.xml b/modules/stock_package_shipping_mygls/view/carrier_form.xml
new file mode 100644
index 0000000000..ed91d9f8e8
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/view/carrier_form.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping_mygls/view/credential_form.xml b/modules/stock_package_shipping_mygls/view/credential_form.xml
new file mode 100644
index 0000000000..10fd3196a5
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/view/credential_form.xml
@@ -0,0 +1,24 @@
+
+
+
diff --git a/modules/stock_package_shipping_mygls/view/credential_list.xml b/modules/stock_package_shipping_mygls/view/credential_list.xml
new file mode 100644
index 0000000000..3c3d77a449
--- /dev/null
+++ b/modules/stock_package_shipping_mygls/view/credential_list.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping_sendcloud/.drone.yml b/modules/stock_package_shipping_sendcloud/.drone.yml
new file mode 100644
index 0000000000..20bb6fbdf9
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/.drone.yml
@@ -0,0 +1,79 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID SENDCLOUD_PUBLIC_KEY SENDCLOUD_SECRET_KEY
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ secrets: [ sendcloud_public_key, sendcloud_secret_key ]
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+ check_doc:
+ image: ${IMAGE}
+ commands:
+ - pip install sphinx
+ - python -m sphinx -T -E -W -n -b html doc _build/html
+ - python -m sphinx -T -E -W -n -b linkcheck doc _build
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_package_shipping_sendcloud/.flake8 b/modules/stock_package_shipping_sendcloud/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_package_shipping_sendcloud/.isort.cfg b/modules/stock_package_shipping_sendcloud/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_package_shipping_sendcloud/CHANGELOG b/modules/stock_package_shipping_sendcloud/CHANGELOG
new file mode 100644
index 0000000000..13acbbdca3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/CHANGELOG
@@ -0,0 +1,14 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Use contact mechanism from address
+
+Version 6.4.0 - 2022-05-02
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+--------------------------
+* Initial release
diff --git a/modules/stock_package_shipping_sendcloud/COPYRIGHT b/modules/stock_package_shipping_sendcloud/COPYRIGHT
new file mode 100644
index 0000000000..852c531661
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2021-2022 B2CK
+Copyright (C) 2021-2022 Cédric Krier
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_package_shipping_sendcloud/LICENSE b/modules/stock_package_shipping_sendcloud/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_package_shipping_sendcloud/MANIFEST.in b/modules/stock_package_shipping_sendcloud/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_package_shipping_sendcloud/README.rst b/modules/stock_package_shipping_sendcloud/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_package_shipping_sendcloud/__init__.py b/modules/stock_package_shipping_sendcloud/__init__.py
new file mode 100644
index 0000000000..e65de2745d
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/__init__.py
@@ -0,0 +1,26 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import carrier, stock
+
+__all__ = ['register']
+
+
+def register():
+ Pool.register(
+ carrier.CredentialSendcloud,
+ carrier.SendcloudAddress,
+ carrier.SendcloudShippingMethod,
+ carrier.Carrier,
+ stock.Package,
+ stock.ShipmentOut,
+ stock.ShipmentInReturn,
+ module='stock_package_shipping_sendcloud', type_='model')
+ Pool.register(
+ stock.CreateShipping,
+ stock.CreateShippingSendcloud,
+ module='stock_package_shipping_sendcloud', type_='wizard')
+ Pool.register(
+ module='stock_package_shipping_sendcloud', type_='report')
diff --git a/modules/stock_package_shipping_sendcloud/carrier.py b/modules/stock_package_shipping_sendcloud/carrier.py
new file mode 100644
index 0000000000..8ceac6295e
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/carrier.py
@@ -0,0 +1,277 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import time
+from functools import wraps
+
+try:
+ from http import HTTPStatus
+except ImportError:
+ from http import client as HTTPStatus
+
+import requests
+
+from trytond.cache import Cache
+from trytond.config import config
+from trytond.i18n import gettext
+from trytond.model import (
+ MatchMixin, ModelSQL, ModelView, fields, sequence_ordered)
+from trytond.pool import PoolMeta
+from trytond.pyson import Eval
+
+from .exceptions import SendcloudError
+
+SENDCLOUD_API_URL = 'https://panel.sendcloud.sc/api/v2/'
+TIMEOUT = config.getfloat(
+ 'stock_package_shipping_sendcloud', 'requests_timeout', default=300)
+
+
+def sendcloud_api(func):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ nb_tries, error_message = 0, ''
+ try:
+ while nb_tries < 5:
+ try:
+ return func(*args, **kwargs)
+ except requests.HTTPError as e:
+ if e.response.status_code == HTTPStatus.TOO_MANY_REQUESTS:
+ error_message = e.args[0]
+ nb_tries += 1
+ time.sleep(1)
+ raise
+ except requests.HTTPError as e:
+ error_message = e.args[0]
+ raise SendcloudError(
+ gettext('stock_package_shipping_sendcloud'
+ '.msg_sendcloud_webserver_error',
+ message=error_message))
+ return wrapper
+
+
+class CredentialSendcloud(sequence_ordered(), ModelSQL, ModelView, MatchMixin):
+ "Sendcloud Credential"
+ __name__ = 'carrier.credential.sendcloud'
+
+ company = fields.Many2One('company.company', "Company")
+ public_key = fields.Char("Public Key", required=True, strip=False)
+ secret_key = fields.Char("Secret Key", required=True, strip=False)
+
+ addresses = fields.One2Many(
+ 'carrier.sendcloud.address', 'sendcloud', "Addresses",
+ states={
+ 'readonly': ~Eval('id') | (Eval('id', -1) < 0),
+ })
+ shipping_methods = fields.One2Many(
+ 'carrier.sendcloud.shipping_method', 'sendcloud', "Methods",
+ states={
+ 'readonly': ~Eval('id') | (Eval('id', -1) < 0),
+ })
+
+ _addresses_sender_cache = Cache(
+ 'carrier.credential.sendcloud.addresses_sender',
+ duration=config.getint(
+ 'stock_package_shipping_sendcloud', 'addresses_cache',
+ default=15 * 60),
+ context=False)
+ _shiping_methods_cache = Cache(
+ 'carrier.credential.sendcloud.shipping_methods',
+ duration=config.getint(
+ 'stock_package_shipping_sendcloud', 'shipping_methods_cache',
+ default=60 * 60))
+
+ @property
+ def auth(self):
+ return self.public_key, self.secret_key
+
+ @property
+ @sendcloud_api
+ def addresses_sender(self):
+ addresses = self._addresses_sender_cache.get(self.id)
+ if addresses is not None:
+ return addresses
+ response = requests.get(
+ SENDCLOUD_API_URL + 'user/addresses/sender',
+ auth=self.auth, timeout=TIMEOUT)
+ response.raise_for_status()
+ addresses = response.json()['sender_addresses']
+ self._addresses_sender_cache.set(self.id, addresses)
+ return addresses
+
+ def get_sender_address(self, shipment):
+ pattern = self._get_sender_address_pattern(shipment)
+ for address in self.addresses:
+ if address.match(pattern):
+ return int(address.address) if address.address else None
+
+ @classmethod
+ def _get_sender_address_pattern(cls, shipment):
+ return {
+ 'warehouse': shipment.shipping_warehouse.id,
+ }
+
+ @sendcloud_api
+ def get_shipping_methods(
+ self, sender_address=None, service_point=None, is_return=False):
+ key = (self.id, sender_address, service_point, is_return)
+ methods = self._shiping_methods_cache.get(key)
+ if methods is not None:
+ return methods
+ params = {}
+ if sender_address:
+ params['sender_address'] = sender_address
+ if service_point:
+ params['service_point'] = service_point
+ if is_return:
+ params['is_return'] = is_return
+ response = requests.get(
+ SENDCLOUD_API_URL + 'shipping_methods', params=params,
+ auth=self.auth, timeout=TIMEOUT)
+ response.raise_for_status()
+ methods = response.json()['shipping_methods']
+ self._shiping_methods_cache.set(key, methods)
+ return methods
+
+ def get_shipping_method(self, shipment):
+ pattern = self._get_shipping_method_pattern(shipment)
+ for method in self.shipping_methods:
+ if method.match(pattern):
+ if method.shipping_method:
+ return int(method.shipping_method)
+ else:
+ return None
+
+ @classmethod
+ def _get_shipping_method_pattern(cls, shipment):
+ return {
+ 'carrier': shipment.carrier.id if shipment.carrier else None,
+ }
+
+ @sendcloud_api
+ def get_parcel(self, id):
+ response = requests.get(
+ SENDCLOUD_API_URL + 'parcels/%s' % id,
+ auth=self.auth, timeout=TIMEOUT)
+ response.raise_for_status()
+ return response.json()['parcel']
+
+ @sendcloud_api
+ def create_parcels(self, parcels):
+ response = requests.post(
+ SENDCLOUD_API_URL + 'parcels', json={'parcels': parcels},
+ auth=self.auth, timeout=TIMEOUT)
+ if response.status_code == 400:
+ msg = response.json()['error']['message']
+ raise requests.HTTPError(msg, response=response)
+ response.raise_for_status()
+ return response.json()['parcels']
+
+ @sendcloud_api
+ def get_label(self, url):
+ response = requests.get(url, auth=self.auth, timeout=TIMEOUT)
+ response.raise_for_status()
+ return response.content
+
+
+class SendcloudAddress(sequence_ordered(), ModelSQL, ModelView, MatchMixin):
+ "Sendcloud Address"
+ __name__ = 'carrier.sendcloud.address'
+
+ sendcloud = fields.Many2One(
+ 'carrier.credential.sendcloud', "Sendcloud", required=True)
+ warehouse = fields.Many2One(
+ 'stock.location', "Warehouse",
+ domain=[
+ ('type', '=', 'warehouse'),
+ ])
+ address = fields.Selection(
+ 'get_addresses', "Address",
+ help="Leave empty for the Sendcloud default.")
+
+ @fields.depends('sendcloud', '_parent_sendcloud.id')
+ def get_addresses(self):
+ addresses = [('', "")]
+ if (self.sendcloud
+ and self.sendcloud.id is not None
+ and self.sendcloud.id >= 0):
+ for address in self.sendcloud.addresses_sender:
+ addresses.append(
+ (str(address['id']), self._format_address(address)))
+ return addresses
+
+ @classmethod
+ def _format_address(cls, address):
+ return ', '.join(
+ filter(None, [
+ address.get('company_name'),
+ address.get('street'),
+ address.get('house_number'),
+ address.get('postal_code'),
+ address.get('city'),
+ address.get('country')]))
+
+
+class SendcloudShippingMethod(
+ sequence_ordered(), ModelSQL, ModelView, MatchMixin):
+ "Sendcloud Shipping Method"
+ __name__ = 'carrier.sendcloud.shipping_method'
+
+ sendcloud = fields.Many2One(
+ 'carrier.credential.sendcloud', "Sendcloud", required=True)
+ carrier = fields.Many2One(
+ 'carrier', "Carrier",
+ domain=[
+ ('shipping_service', '=', 'sendcloud'),
+ ])
+ shipping_method = fields.Selection(
+ 'get_shipping_methods', "Shipping Method")
+
+ @fields.depends('sendcloud', '_parent_sendcloud.id')
+ def get_shipping_methods(self):
+ methods = [(None, '')]
+ if (self.sendcloud
+ and self.sendcloud.id is not None
+ and self.sendcloud.id >= 0):
+ methods += [
+ (str(m['id']), m['name'])
+ for m in self.sendcloud.get_shipping_methods()]
+ return methods
+
+
+class Carrier(metaclass=PoolMeta):
+ __name__ = 'carrier'
+
+ sendcloud_format = fields.Selection([
+ ('normal 0', "A4 - Top left"),
+ ('normal 1', "A4 - Top right"),
+ ('normal 2', "A4 - Bottom left"),
+ ('normal 3', "A4 - Bottom right"),
+ ('label', "A6 - Full page"),
+ ], "Format",
+ states={
+ 'invisible': Eval('shipping_service') != 'sendcloud',
+ 'required': Eval('shipping_service') == 'sendcloud',
+ })
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls.shipping_service.selection.append(('sendcloud', "Sendcloud"))
+
+ @classmethod
+ def default_sendcloud_format(cls):
+ return 'label'
+
+ @classmethod
+ def view_attributes(cls):
+ return super(Carrier, cls).view_attributes() + [
+ ("/form/separator[@id='sendcloud']", 'states', {
+ 'invisible': Eval('shipping_service') != 'sendcloud',
+ }),
+ ]
+
+ @property
+ def shipping_label_mimetype(self):
+ mimetype = super().shipping_label_mimetype
+ if self.shipping_service == 'sendcloud':
+ mimetype = 'application/pdf'
+ return mimetype
diff --git a/modules/stock_package_shipping_sendcloud/carrier.xml b/modules/stock_package_shipping_sendcloud/carrier.xml
new file mode 100644
index 0000000000..e34e4c18c7
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/carrier.xml
@@ -0,0 +1,113 @@
+
+
+
+
+
+ carrier.credential.sendcloud
+ form
+ credential_form
+
+
+ carrier.credential.sendcloud
+ tree
+ credential_list
+
+
+
+ Sendcloud Credentials
+ carrier.credential.sendcloud
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ carrier.sendcloud.address
+ form
+ carrier_address_form
+
+
+ carrier.sendcloud.address
+ tree
+ carrier_address_list
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ carrier.sendcloud.shipping_method
+ form
+ carrier_shipping_method_form
+
+
+ carrier.sendcloud.shipping_method
+ tree
+ carrier_shipping_method_list
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ carrier
+
+ carrier_form
+
+
+
diff --git a/modules/stock_package_shipping_sendcloud/doc/conf.py b/modules/stock_package_shipping_sendcloud/doc/conf.py
new file mode 100644
index 0000000000..8513b72dd2
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/doc/conf.py
@@ -0,0 +1,61 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+modules_url = 'https://docs.tryton.org/projects/modules-{module}/en/{series}/'
+trytond_url = 'https://docs.tryton.org/projects/server/en/{series}/'
+
+
+def get_info():
+ import configparser
+ import os
+ import subprocess
+ import sys
+
+ module_dir = os.path.dirname(os.path.dirname(__file__))
+
+ config = configparser.ConfigParser()
+ config.read_file(open(os.path.join(module_dir, 'tryton.cfg')))
+ info = dict(config.items('tryton'))
+
+ result = subprocess.run(
+ [sys.executable, 'setup.py', '--name'],
+ stdout=subprocess.PIPE, check=True, cwd=module_dir)
+ info['name'] = result.stdout.decode('utf-8').strip()
+
+ result = subprocess.run(
+ [sys.executable, 'setup.py', '--version'],
+ stdout=subprocess.PIPE, check=True, cwd=module_dir)
+ version = result.stdout.decode('utf-8').strip()
+ if 'dev' in version:
+ info['series'] = 'latest'
+ else:
+ info['series'] = '.'.join(version.split('.', 2)[:2])
+
+ for key in {'depends', 'extras_depend'}:
+ info[key] = info.get(key, '').strip().splitlines()
+ info['modules'] = set(info['depends'] + info['extras_depend'])
+ info['modules'] -= {'ir', 'res'}
+
+ return info
+
+
+info = get_info()
+
+master_doc = 'index'
+project = info['name']
+release = version = info['series']
+default_role = 'ref'
+highlight_language = 'none'
+extensions = [
+ 'sphinx.ext.intersphinx',
+ ]
+intersphinx_mapping = {
+ 'trytond': (trytond_url.format(series=version), None),
+ }
+intersphinx_mapping.update({
+ m: (modules_url.format(
+ module=m.replace('_', '-'), series=version), None)
+ for m in info['modules']
+ })
+
+del get_info, info, modules_url, trytond_url
diff --git a/modules/stock_package_shipping_sendcloud/doc/configuration.rst b/modules/stock_package_shipping_sendcloud/doc/configuration.rst
new file mode 100644
index 0000000000..84e874d2cd
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/doc/configuration.rst
@@ -0,0 +1,37 @@
+*************
+Configuration
+*************
+
+The *Stock Package Shipping Sendcloud Module* uses values from settings in the
+``[stock_package_shipping_sendcloud]`` section of the :doc:`configuration file
+`.
+
+.. _config-stock_package_shipping_sendcloud.addresses_cache:
+
+``addresses_cache``
+===================
+
+The ``addresses_cache`` defines the duration in seconds the sender addresses
+are kept in the cache.
+
+The default value is: ``15 * 60``.
+
+.. _config-stock_package_shipping_sendcloud.shipping_methods_cache:
+
+``shipping_methods_cache``
+==========================
+
+The ``shipping_methods_cache`` defines the duration in seconds the shipping
+methods are kept in the cache.
+
+The default value is: ``60 * 60``.
+
+.. _config-stock_package_shipping_sendcloud.requests_timeout:
+
+``requests_timeout``
+====================
+
+The ``requests_timeout`` defines the time in seconds the module is waiting for
+a response from the Sendcloud server.
+
+The default value is: ``300``.
diff --git a/modules/stock_package_shipping_sendcloud/doc/design.rst b/modules/stock_package_shipping_sendcloud/doc/design.rst
new file mode 100644
index 0000000000..f95e3e346e
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/doc/design.rst
@@ -0,0 +1,41 @@
+******
+Design
+******
+
+The *Stock Package Shipping Sendcloud Module* introduces the following concepts:
+
+.. _model-carrier.credential.sendcloud:
+
+Sendcloud Credential
+====================
+
+This is used to store the credentials needed to connect to the Sendcloud API.
+It also defines the sender address for each warehouse and the shipping method
+for each carrier.
+
+.. note::
+
+ For carriers without a shipping method, the Sendcloud rules are applied.
+
+.. seealso::
+
+ The credentials can be accessed from the main menu item:
+
+ |Carrier --> Configuration --> Sendcloud Credentials|__
+
+ .. |Carrier --> Configuration --> Sendcloud Credentials| replace:: :menuselection:`Carrier --> Configuration --> Sendcloud Credentials`
+ __ https://demo.tryton.org/model/carrier.credential.sendcloud
+
+.. _model-carrier:
+
+Carrier
+=======
+
+When the *Stock Package Shipping Sendcloud Module* is activated, carriers gain
+some extra properties.
+These include a new shipping service "Sendcloud" and a label format.
+
+.. seealso::
+
+ The :doc:`Carrier ` concept is introduced by the
+ :doc:`Carrier Module `.
diff --git a/modules/stock_package_shipping_sendcloud/doc/index.rst b/modules/stock_package_shipping_sendcloud/doc/index.rst
new file mode 100644
index 0000000000..61f85951ed
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/doc/index.rst
@@ -0,0 +1,14 @@
+#######################################
+Stock Package Shipping Sendcloud Module
+#######################################
+
+The *Stock Package Shipping Sendcloud Module* allows package labels to be
+generated for shipments made by any of `Sendcloud's
+`_ supported carriers.
+
+.. toctree::
+ :maxdepth: 2
+
+ configuration
+ design
+ releases
diff --git a/modules/stock_package_shipping_sendcloud/doc/releases.rst b/modules/stock_package_shipping_sendcloud/doc/releases.rst
new file mode 100644
index 0000000000..21b13c4745
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/doc/releases.rst
@@ -0,0 +1,7 @@
+.. _releases-index:
+
+=============
+Release notes
+=============
+
+.. include:: ../CHANGELOG
diff --git a/modules/stock_package_shipping_sendcloud/exceptions.py b/modules/stock_package_shipping_sendcloud/exceptions.py
new file mode 100644
index 0000000000..718b43637b
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/exceptions.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.exceptions import UserError
+
+
+class SendcloudError(UserError):
+ pass
diff --git a/modules/stock_package_shipping_sendcloud/locale/bg.po b/modules/stock_package_shipping_sendcloud/locale/bg.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/bg.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/ca.po b/modules/stock_package_shipping_sendcloud/locale/ca.po
new file mode 100644
index 0000000000..1a5ea86d66
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/ca.po
@@ -0,0 +1,131 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr "Format"
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr "Adreces"
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr "Clau pública"
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr "Clau secreta"
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr "Mètodes"
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr "Adreça"
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr "Magatzem"
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr "Transportista"
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr "Mètode d'enviament"
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr "ID"
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr "URL de seguiment"
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr "Deixar buit per al valor per defecte de Sendcloud."
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr "Credencial Sendcloud"
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr "Adreça Sendcloud"
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr "Mètode d'enviament Sendcloud"
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr "Crear enviament Sendcloud pels paquets"
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr "Credencials Sendcloud"
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"La trucada del servei web Sendcloud ha fallat amb el següent missatge d'error:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+"No podeu crear una etiqueta d'enviament per l'albarà \"%(shipment)s\" perquè"
+" ja té un número de referència."
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr "Credencials Sendcloud"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr "A4 - A baix a l'esquerra"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr "A4 - A baix a la dreta"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr "A4 - A dalt a l'esquerra"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr "A4 - A dalt a la dreta"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr "A6 - Pàgina completa"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
diff --git a/modules/stock_package_shipping_sendcloud/locale/cs.po b/modules/stock_package_shipping_sendcloud/locale/cs.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/cs.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/de.po b/modules/stock_package_shipping_sendcloud/locale/de.po
new file mode 100644
index 0000000000..dd9dc530a5
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/de.po
@@ -0,0 +1,131 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr "Format"
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr "Adressen"
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr "Unternehmen"
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr "Öffentlicher Schlüssel"
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr "Geheimer Schlüssel"
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr "Methoden"
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr "Adresse"
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr "Logistikstandort"
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr "Versanddienstleister"
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr "Versandart"
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr "ID"
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr "Tracking-URL"
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr "Leer lassen für Sendcloud Standard."
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr "Sendcloud Anmeldedaten"
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr "Sendcloud Adresse"
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr "Sendcloud Versandart"
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr "Sendcloud Versandauftrag für Pakete erstellen"
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr "Sendcloud Anmeldedaten"
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"Beim Aufruf des Sendcloud Webservice ist folgender Fehler aufgetreten:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+"Es kann kein Versandetikett für die Lieferung \"%(shipment)s\" erstellt "
+"werden, weil bereits eine Referenznummer vorhanden ist."
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr "Sendcloud Anmeldedaten"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr "A4 - Unten links"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr "A4 - Unten rechts"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr "A4 - Oben links"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr "A4 - Oben rechts"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr "A6 - Ganze Seite"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
diff --git a/modules/stock_package_shipping_sendcloud/locale/es.po b/modules/stock_package_shipping_sendcloud/locale/es.po
new file mode 100644
index 0000000000..217a78c4ae
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/es.po
@@ -0,0 +1,131 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr "Formato"
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr "Direcciones"
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr "Clave pública"
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr "Clave secreta"
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr "Métodos"
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr "Dirección"
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr "Almacén"
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr "Transportista"
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr "Método de envío"
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr "ID"
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr "URL Seguimiento"
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr "Dejar vacío para el valor por defecto de Sendcloud."
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr "Credencial Sendcloud"
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr "Dirección Sendcloud"
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr "Método de envío Sendcloud"
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr "Crear envío Sendcloud para paquetes"
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr "Credenciales Sendcloud"
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"La llamada al servicio web de Sendcloud ha fallado con el siguiente mensaje de error:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+"No puedes crear una etiqueta de envío para el albarán \"%(shipment)s\" "
+"porque ya tiene un número de referencia."
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr "Credenciales Sendcloud"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr "A4 - Abajo a la izquierda"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr "A4 - Abajo a la derecha"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr "A4 - Arriba a la izquierda"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr "A4 - Arriba a la derecha"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr "A6 - Página completa"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
diff --git a/modules/stock_package_shipping_sendcloud/locale/es_419.po b/modules/stock_package_shipping_sendcloud/locale/es_419.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/es_419.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/et.po b/modules/stock_package_shipping_sendcloud/locale/et.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/et.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/fa.po b/modules/stock_package_shipping_sendcloud/locale/fa.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/fa.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/fi.po b/modules/stock_package_shipping_sendcloud/locale/fi.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/fi.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/fr.po b/modules/stock_package_shipping_sendcloud/locale/fr.po
new file mode 100644
index 0000000000..ad3bf36ce6
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/fr.po
@@ -0,0 +1,131 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr "Format"
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr "Adresses"
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr "Société"
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr "Clé publique"
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr "Clé secrète"
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr "Méthodes"
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr "Adresse"
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr "Entrepôt"
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr "Transporteur"
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr "Méthode d'expédition"
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr "ID"
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr "URL de suivi"
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr "Laissez vide pour la valeur par défaut de Sendcloud."
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr "Identifiant Sendcloud"
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr "Adresse Sendcloud"
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr "Méthode de livraison Sendcloud"
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr "Créer la livraison Sendcloud pour les emballages"
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr "Identifiants Sendcloud"
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"L'appel au service web de Sendcloud a échoué avec le message d'erreur suivant :\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+"Vous ne pouvez pas créer d'étiquette de livraison pour l'expédition "
+"« %(shipment)s » car elle a déjà un numéro de référence."
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr "Identifiants Sendcloud"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr "A4 - En bas à gauche"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr "A4 - En bas à droite"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr "A4 - En haut à gauche"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr "A4 - En haut à droite"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr "A6 - Pleine page"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
diff --git a/modules/stock_package_shipping_sendcloud/locale/hu.po b/modules/stock_package_shipping_sendcloud/locale/hu.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/hu.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/id.po b/modules/stock_package_shipping_sendcloud/locale/id.po
new file mode 100644
index 0000000000..c68b4416ff
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/id.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr "Perusahaan"
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr "Alamat"
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/it.po b/modules/stock_package_shipping_sendcloud/locale/it.po
new file mode 100644
index 0000000000..55a16d860e
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/it.po
@@ -0,0 +1,131 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr "Formato"
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr "Indirizzi"
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr "Azienda"
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr "Chiave pubblica"
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr "Chiave segreta"
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr "Metodi"
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr "Indirizzo"
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr "Magazzino"
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr "Vettore"
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr "Metodo di spedizione"
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr "ID"
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr "URL di tracciamento"
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr "Lascia vuoto per l'impostazione predefinita di Sendcloud."
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr "Credenziali Sendcloud"
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr "Indirizzo Sendcloud"
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr "Metodo di spedizione Sendcloud"
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr "Crea spedizione Sendcloud per i pacchi"
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr "Credenziali Sendcloud"
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"La chiamata al servizio web Sendcloud non è fallita con il seguente messaggio di errore:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+"Non puoi creare un'etichetta di spedizione per la spedizione "
+"\"%(shipment)s\" perché ha già un numero di riferimento."
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr "Credenziali Sendcloud"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr "A4 - In basso a sinistra"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr "A4 - In basso a destra"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr "A4 - In alto a sinistra"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr "A4 - In alto a destra"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr "A6 - Pagina intera"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
diff --git a/modules/stock_package_shipping_sendcloud/locale/lo.po b/modules/stock_package_shipping_sendcloud/locale/lo.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/lo.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/lt.po b/modules/stock_package_shipping_sendcloud/locale/lt.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/lt.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/nl.po b/modules/stock_package_shipping_sendcloud/locale/nl.po
new file mode 100644
index 0000000000..9962b9e83b
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/nl.po
@@ -0,0 +1,131 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr "Formaat"
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr "Adressen"
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr "Bedrijf"
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr "Publieke sleutel"
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr "Geheime sleutel"
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr "Methodes"
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr "Adres"
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr "Magazijn"
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr "Transporteur"
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr "Verzendwijze"
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr "ID"
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr "Tracking-URL"
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr "Laat leeg voor de Sendcloud-standaard."
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr "Sendcloud-referentie"
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr "Sendcloud-adres"
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr "Sendcloud Verzendmethode"
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr "Creëer Sendcloud-verzending voor pakketten"
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr "Sendcloud-referentie"
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"Bij het oproepen van de Sendcloud webservice is volgende fout opgetreden:\n"
+"%(bericht)s"
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+"U kunt geen verzendlabel maken voor verzending \"%(shipment)s\", omdat deze "
+"al een referentienummer heeft."
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr "Sendcloud-referentie"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr "A4 - Linksonder"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr "A4 - Rechtsonder"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr "A4 - Linksboven"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr "A4 - Rechtsboven"
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr "A6 - Volledige pagina"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr "Sendcloud"
diff --git a/modules/stock_package_shipping_sendcloud/locale/pl.po b/modules/stock_package_shipping_sendcloud/locale/pl.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/pl.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/pt.po b/modules/stock_package_shipping_sendcloud/locale/pt.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/pt.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/ro.po b/modules/stock_package_shipping_sendcloud/locale/ro.po
new file mode 100644
index 0000000000..0211ac305c
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/ro.po
@@ -0,0 +1,129 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+"Nu se poate crea o eticheta pentru expedierea \"%(shipment)s\" pentru că are"
+" deja un număr de referinţa."
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/ru.po b/modules/stock_package_shipping_sendcloud/locale/ru.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/ru.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/sl.po b/modules/stock_package_shipping_sendcloud/locale/sl.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/sl.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/tr.po b/modules/stock_package_shipping_sendcloud/locale/tr.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/tr.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/uk.po b/modules/stock_package_shipping_sendcloud/locale/uk.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/uk.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/locale/zh_CN.po b/modules/stock_package_shipping_sendcloud/locale/zh_CN.po
new file mode 100644
index 0000000000..48b66554c3
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/locale/zh_CN.po
@@ -0,0 +1,127 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,sendcloud_format:"
+msgid "Format"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,addresses:"
+msgid "Addresses"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,public_key:"
+msgid "Public Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,secret_key:"
+msgid "Secret Key"
+msgstr ""
+
+msgctxt "field:carrier.credential.sendcloud,shipping_methods:"
+msgid "Methods"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,address:"
+msgid "Address"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.address,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,sendcloud:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "field:carrier.sendcloud.shipping_method,shipping_method:"
+msgid "Shipping Method"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_id:"
+msgid "ID"
+msgstr ""
+
+msgctxt "field:stock.package,sendcloud_shipping_tracking_url:"
+msgid "Tracking URL"
+msgstr ""
+
+msgctxt "help:carrier.sendcloud.address,address:"
+msgid "Leave empty for the Sendcloud default."
+msgstr ""
+
+msgctxt "model:carrier.credential.sendcloud,name:"
+msgid "Sendcloud Credential"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.address,name:"
+msgid "Sendcloud Address"
+msgstr ""
+
+msgctxt "model:carrier.sendcloud.shipping_method,name:"
+msgid "Sendcloud Shipping Method"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_wizard"
+msgid "Create Sendcloud Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sendcloud_webserver_error"
+msgid ""
+"Sendcloud webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create a shipping label for shipment \"%(shipment)s\" because it "
+"already has a reference number."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_credential_form"
+msgid "Sendcloud Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Bottom right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top left"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A4 - Top right"
+msgstr ""
+
+msgctxt "selection:carrier,sendcloud_format:"
+msgid "A6 - Full page"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "Sendcloud"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "Sendcloud"
+msgstr ""
diff --git a/modules/stock_package_shipping_sendcloud/message.xml b/modules/stock_package_shipping_sendcloud/message.xml
new file mode 100644
index 0000000000..38bc7cb35a
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/message.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ Sendcloud webservice call failed with the following error message:
+%(message)s
+
+
+ You cannot create a shipping label for shipment "%(shipment)s" because it already has a reference number.
+
+
+
diff --git a/modules/stock_package_shipping_sendcloud/setup.py b/modules/stock_package_shipping_sendcloud/setup.py
new file mode 100755
index 0000000000..248f3424b4
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/setup.py
@@ -0,0 +1,163 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ content = io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+ content = re.sub(
+ r'(?m)^\.\. toctree::\r?\n((^$|^\s.*$)\r?\n)*', '', content)
+ return content
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_package_shipping_sendcloud'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+requires = ['requests']
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [
+ get_require_version('proteus'),
+ get_require_version('trytond_sale'),
+ get_require_version('trytond_sale_shipment_cost'),
+ ]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version)
+ )
+
+setup(name=name,
+ version=version,
+ description='Sendcloud connector for the Tryton application platform',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": (
+ 'https://docs.tryton.org/projects/'
+ 'modules-stock-package-shipping-sendcloud'),
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": (
+ 'https://hg.tryton.org/modules/stock_package_shipping_sendcloud'),
+ },
+ keywords='tryton stock package shipping sendcloud',
+ package_dir={'trytond.modules.stock_package_shipping_sendcloud': '.'},
+ packages=(
+ ['trytond.modules.stock_package_shipping_sendcloud']
+ + ['trytond.modules.stock_package_shipping_sendcloud.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_package_shipping_sendcloud': (
+ info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_package_shipping_sendcloud = trytond.modules.stock_package_shipping_sendcloud
+ """, # noqa: E501
+ )
diff --git a/modules/stock_package_shipping_sendcloud/stock.py b/modules/stock_package_shipping_sendcloud/stock.py
new file mode 100644
index 0000000000..64c95a4710
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/stock.py
@@ -0,0 +1,185 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from itertools import zip_longest
+
+from trytond.i18n import gettext
+from trytond.model import fields
+from trytond.model.exceptions import AccessError
+from trytond.pool import Pool, PoolMeta
+from trytond.transaction import Transaction
+from trytond.wizard import StateAction, StateTransition, Wizard
+
+
+class Package(metaclass=PoolMeta):
+ __name__ = 'stock.package'
+
+ sendcloud_shipping_id = fields.Integer("ID", readonly=True)
+ sendcloud_shipping_tracking_url = fields.Char(
+ "Tracking URL", readonly=True)
+
+ def get_shipping_tracking_url(self, name):
+ url = super().get_shipping_tracking_url(name)
+ if (self.shipping_reference
+ and self.shipment
+ and self.shipment.id >= 0
+ and self.shipment.carrier
+ and self.shipment.carrier.shipping_service == 'sendcloud'):
+ url = self.sendcloud_shipping_tracking_url
+ return url
+
+ @classmethod
+ def copy(cls, packages, default=None):
+ if default is None:
+ default = {}
+ else:
+ default = default.copy()
+ default.setdefault('sendcloud_shipping_id')
+ default.setdefault('sendcloud_shipping_tracking_url')
+ return super().copy(packages, default=default)
+
+
+class ShippingSendcloudMixin:
+ __slots__ = ()
+
+ def get_sendcloud_credential(self):
+ pool = Pool()
+ SendcloudCredential = pool.get('carrier.credential.sendcloud')
+
+ pattern = self._get_sendcloud_credential_pattern()
+ for credential in SendcloudCredential.search([]):
+ if credential.match(pattern):
+ return credential
+
+ def _get_sendcloud_credential_pattern(self):
+ return {
+ 'company': self.company.id,
+ }
+
+ def validate_packing_sendcloud(self):
+ pass
+
+
+class ShipmentOut(ShippingSendcloudMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out'
+
+
+class ShipmentInReturn(ShippingSendcloudMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in.return'
+
+
+class CreateShipping(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.create_shipping'
+
+ sendcloud = StateAction(
+ 'stock_package_shipping_sendcloud.act_create_shipping_wizard')
+
+ def transition_start(self):
+ next_state = super().transition_start()
+ if self.record.carrier.shipping_service == 'sendcloud':
+ next_state = 'sendcloud'
+ return next_state
+
+ def do_sendcloud(self, action):
+ ctx = Transaction().context
+ return action, {
+ 'model': ctx['active_model'],
+ 'id': ctx['active_id'],
+ 'ids': [ctx['active_id']],
+ }
+
+
+class CreateShippingSendcloud(Wizard):
+ "Create Sendcloud Shipping"
+ __name__ = 'stock.shipment.create_shipping.sendcloud'
+
+ start = StateTransition()
+
+ def transition_start(self):
+ pool = Pool()
+ Package = pool.get('stock.package')
+
+ shipment = self.record
+ if shipment.reference:
+ raise AccessError(
+ gettext('stock_package_shipping_sendcloud'
+ '.msg_shipment_has_reference_number',
+ shipment=shipment.rec_name))
+
+ credential = shipment.get_sendcloud_credential()
+ carrier = shipment.carrier
+ packages = shipment.root_packages
+
+ parcels = []
+ for package in packages:
+ parcels.append(self.get_parcel(shipment, package, credential))
+ parcels = credential.create_parcels(parcels)
+
+ for package, parcel in zip_longest(packages, parcels):
+ format_ = shipment.carrier.sendcloud_format.split()
+ label_url = parcel['label']
+ for key in format_:
+ try:
+ index = int(key)
+ except ValueError:
+ key += '_printer'
+ label_url = label_url[key]
+ else:
+ label_url = label_url[index]
+ package.sendcloud_shipping_id = parcel['id']
+ package.shipping_label = credential.get_label(label_url)
+ package.shipping_label_mimetype = carrier.shipping_label_mimetype
+ package.shipping_reference = parcel['tracking_number']
+ package.sendcloud_shipping_tracking_url = parcel['tracking_url']
+ if not shipment.reference:
+ shipment.reference = (
+ parcel['colli_tracking_number']
+ or parcel['tracking_number'])
+ Package.save(packages)
+ shipment.save()
+
+ return 'end'
+
+ def get_parcel(self, shipment, package, credential, usage=None):
+ pool = Pool()
+ UoM = pool.get('product.uom')
+ ModelData = pool.get('ir.model.data')
+
+ cm = UoM(ModelData.get_id('product', 'uom_centimeter'))
+ party = shipment.shipping_to
+ address = shipment.shipping_to_address
+ phone = address.contact_mechanism_get(
+ {'phone', 'mobile'}, usage=usage)
+ email = address.contact_mechanism_get('email', usage=usage)
+ street_lines = (address.street or '').splitlines()
+ parcel = {
+ 'name': address.party_full_name,
+ 'company_name': (
+ party.full_name if party.full_name != address.party_full_name
+ else None),
+ 'address': street_lines[0] if street_lines else '',
+ 'address_2': (
+ ' '.join(street_lines[1:]) if len(street_lines) > 1 else ''),
+ 'city': address.city,
+ 'postal_code': address.postal_code,
+ 'country': address.country.code if address.country else None,
+ 'country_state': (
+ address.subdivision.code.split('-', 1)[1]
+ if address.subdivision else None),
+ 'telephone': phone.value if phone else None,
+ 'email': email.value if email else None,
+ 'sender_address': credential.get_sender_address(shipment),
+ 'external_reference': '/'.join([shipment.number, package.code]),
+ 'quantity': 1,
+ 'order_number': shipment.number,
+ 'weight': package.total_weight,
+ 'length': UoM.compute_qty(package.length_uom, package.length, cm),
+ 'width': UoM.compute_qty(package.width_uom, package.width, cm),
+ 'height': UoM.compute_qty(package.height_uom, package.height, cm),
+ 'request_label': True,
+ }
+ shipping_method = credential.get_shipping_method(shipment)
+ if shipping_method:
+ parcel['shipment'] = {'id': shipping_method}
+ else:
+ parcel['apply_shipping_rules'] = True
+ return parcel
diff --git a/modules/stock_package_shipping_sendcloud/stock.xml b/modules/stock_package_shipping_sendcloud/stock.xml
new file mode 100644
index 0000000000..10b79641dc
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/stock.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+ Create Sendcloud Shipping for Packages
+ stock.shipment.create_shipping.sendcloud
+
+
+
diff --git a/modules/stock_package_shipping_sendcloud/tests/__init__.py b/modules/stock_package_shipping_sendcloud/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_package_shipping_sendcloud/tests/scenario_stock_package_shipping_sendcloud.rst b/modules/stock_package_shipping_sendcloud/tests/scenario_stock_package_shipping_sendcloud.rst
new file mode 100644
index 0000000000..e7f956bb2a
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/tests/scenario_stock_package_shipping_sendcloud.rst
@@ -0,0 +1,232 @@
+=========================================
+Stock Package Shipping Sendcloud Scenario
+=========================================
+
+Imports::
+
+ >>> import os
+ >>> from decimal import Decimal
+ >>> from random import randint
+
+ >>> import requests
+
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import (
+ ... create_company, get_company)
+ >>> from trytond.modules.account.tests.tools import (
+ ... create_fiscalyear, create_chart, get_accounts)
+ >>> from trytond.modules.account_invoice.tests.tools import (
+ ... set_fiscalyear_invoice_sequences)
+ >>> from trytond.modules.stock_package_shipping_sendcloud.carrier import (
+ ... SENDCLOUD_API_URL)
+
+Activate modules::
+
+ >>> config = activate_modules(
+ ... ['stock_package_shipping_sendcloud', 'sale', 'sale_shipment_cost'])
+
+ >>> Address = Model.get('party.address')
+ >>> Carrier = Model.get('carrier')
+ >>> CarrierAddress = Model.get('carrier.sendcloud.address')
+ >>> CarrierShippingMethod = Model.get('carrier.sendcloud.shipping_method')
+ >>> Country = Model.get('country.country')
+ >>> Credential = Model.get('carrier.credential.sendcloud')
+ >>> Location = Model.get('stock.location')
+ >>> Package = Model.get('stock.package')
+ >>> PackageType = Model.get('stock.package.type')
+ >>> Party = Model.get('party.party')
+ >>> ProductCategory = Model.get('product.category')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> ProductUoM = Model.get('product.uom')
+ >>> Sale = Model.get('sale.sale')
+ >>> StockConfiguration = Model.get('stock.configuration')
+ >>> UoM = Model.get('product.uom')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create fiscal year::
+
+ >>> fiscalyear = set_fiscalyear_invoice_sequences(
+ ... create_fiscalyear(company))
+ >>> fiscalyear.click('create_period')
+
+Create chart of accounts::
+
+ >>> _ = create_chart(company)
+ >>> accounts = get_accounts(company)
+
+Set random sequence::
+
+ >>> stock_config = StockConfiguration(1)
+ >>> stock_config.shipment_out_sequence.number_next = randint(1, 10**6)
+ >>> stock_config.shipment_out_sequence.save()
+ >>> stock_config.package_sequence.number_next = randint(1, 10**6)
+ >>> stock_config.package_sequence.save()
+
+Create parties::
+
+ >>> belgium = Country(code='BE', name='Belgium')
+ >>> belgium.save()
+ >>> france = Country(code='FR', name='France')
+ >>> subdivision = france.subdivisions.new()
+ >>> subdivision.name = "Paris"
+ >>> subdivision.code = 'FR-75'
+ >>> subdivision.type = 'metropolitan department'
+ >>> france.save()
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+ >>> customer_address = customer.addresses.new()
+ >>> customer_address.street = 'Champs élysées'
+ >>> customer_address.postal_code = '75008'
+ >>> customer_address.city = 'Paris'
+ >>> customer_address.country = france
+ >>> customer_address.subdivision = france.subdivisions[0]
+ >>> customer_address.save()
+ >>> customer_phone = customer.contact_mechanisms.new()
+ >>> customer_phone.type = 'phone'
+ >>> customer_phone.value = '+33 93 842 8862'
+ >>> customer_phone.save()
+
+Set the warehouse address::
+
+ >>> warehouse, = Location.find([('type', '=', 'warehouse')])
+ >>> company_address = Address()
+ >>> company_address.party = company.party
+ >>> company_address.street = '2 rue de la Centrale'
+ >>> company_address.postal_code = '4000'
+ >>> company_address.city = 'Sclessin'
+ >>> company_address.country = belgium
+ >>> company_address.save()
+ >>> company_phone = company.party.contact_mechanisms.new()
+ >>> company_phone.type = 'phone'
+ >>> company_phone.value = '+32 4 2522122'
+ >>> company_phone.save()
+ >>> warehouse.address = company_address
+ >>> warehouse.save()
+
+Get some units::
+
+ >>> cm, = UoM.find([('symbol', '=', 'cm')])
+ >>> g, = UoM.find([('symbol', '=', 'g')])
+
+Create account category::
+
+ >>> account_category = ProductCategory(name="Account Category")
+ >>> account_category.accounting = True
+ >>> account_category.account_expense = accounts['expense']
+ >>> account_category.account_revenue = accounts['revenue']
+ >>> account_category.save()
+
+Create product::
+
+ >>> unit, = ProductUoM.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.salable = True
+ >>> template.weight = 100
+ >>> template.weight_uom = g
+ >>> template.list_price = Decimal('10')
+ >>> template.account_category = account_category
+ >>> template.save()
+ >>> product, = template.products
+
+Create Package Type::
+
+ >>> box = PackageType(
+ ... name="Box",
+ ... length=10, length_uom=cm,
+ ... height=8, height_uom=cm,
+ ... width=1, width_uom=cm)
+ >>> box.save()
+
+Create a Sendcloud Carrier and the related credentials::
+
+ >>> credential = Credential()
+ >>> credential.company = company
+ >>> credential.public_key = os.getenv('SENDCLOUD_PUBLIC_KEY')
+ >>> credential.secret_key = os.getenv('SENDCLOUD_SECRET_KEY')
+ >>> credential.save()
+ >>> address = credential.addresses.new()
+ >>> address.warehouse = warehouse
+ >>> address.address = CarrierAddress.get_addresses(
+ ... {'id': address.id, 'sendcloud': {'id': credential.id}},
+ ... address._context)[-1][0]
+ >>> shipping_method = credential.shipping_methods.new()
+ >>> shipping_method.shipping_method, = [
+ ... m[0] for m in CarrierShippingMethod.get_shipping_methods(
+ ... {'id': shipping_method.id, 'sendcloud': {'id': credential.id}},
+ ... shipping_method._context)
+ ... if m[1] == "Unstamped letter"]
+ >>> credential.save()
+
+ >>> template = ProductTemplate()
+ >>> template.name = "Sendcloud"
+ >>> template.default_uom = unit
+ >>> template.type = 'service'
+ >>> template.salable = True
+ >>> template.list_price = Decimal(20)
+ >>> template.account_category = account_category
+ >>> template.save()
+ >>> carrier_product, = template.products
+
+ >>> sendcloud = Party(name="Sendcloud")
+ >>> sendcloud.save()
+
+ >>> carrier = Carrier()
+ >>> carrier.party = sendcloud
+ >>> carrier.carrier_product = carrier_product
+ >>> carrier.shipping_service = 'sendcloud'
+ >>> carrier.save()
+
+Create a sale and thus a shipment::
+
+ >>> sale = Sale()
+ >>> sale.party = customer
+ >>> sale.shipment_address = customer_address
+ >>> sale.invoice_method = 'order'
+ >>> sale.carrier = carrier
+ >>> sale_line = sale.lines.new()
+ >>> sale_line.product = product
+ >>> sale_line.quantity = 2.0
+ >>> sale.click('quote')
+ >>> sale.click('confirm')
+ >>> sale.click('process')
+
+Create the packages and ship the shipment::
+
+ >>> shipment, = sale.shipments
+ >>> shipment.click('assign_force')
+ >>> shipment.click('pick')
+ >>> pack = shipment.packages.new()
+ >>> pack.type = box
+ >>> pack_move, = pack.moves.find([])
+ >>> pack.moves.append(pack_move)
+ >>> shipment.click('pack')
+
+ >>> create_shipping = Wizard('stock.shipment.create_shipping', [shipment])
+ >>> shipment.reload()
+ >>> bool(shipment.reference)
+ True
+ >>> pack, = shipment.root_packages
+ >>> bool(pack.sendcloud_shipping_id)
+ True
+ >>> pack.shipping_label is not None
+ True
+ >>> pack.shipping_label_mimetype
+ 'application/pdf'
+ >>> pack.shipping_reference is not None
+ True
+ >>> pack.shipping_tracking_url.startswith('http')
+ True
+
+Clean up::
+
+ >>> _ = requests.post(SENDCLOUD_API_URL + 'parcels/%s/cancel' % pack.sendcloud_shipping_id,
+ ... auth=(credential.public_key, credential.secret_key))
diff --git a/modules/stock_package_shipping_sendcloud/tests/test_module.py b/modules/stock_package_shipping_sendcloud/tests/test_module.py
new file mode 100644
index 0000000000..dc25872f8c
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/tests/test_module.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockPackageShippingSendcloudTestCase(ModuleTestCase):
+ 'Test Stock Package Shipping Sendcloud module'
+ module = 'stock_package_shipping_sendcloud'
+
+
+del ModuleTestCase
diff --git a/modules/stock_package_shipping_sendcloud/tests/test_scenario.py b/modules/stock_package_shipping_sendcloud/tests/test_scenario.py
new file mode 100644
index 0000000000..a1a5c197f4
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/tests/test_scenario.py
@@ -0,0 +1,11 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import os
+
+from trytond.tests.test_tryton import load_doc_tests
+
+if (os.getenv('SENDCLOUD_PUBLIC_KEY')
+ and os.getenv('SENDCLOUD_SECRET_KEY')):
+ def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_package_shipping_sendcloud/tox.ini b/modules/stock_package_shipping_sendcloud/tox.ini
new file mode 100644
index 0000000000..5cb067a731
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_package_shipping_sendcloud/* -m unittest discover -s tests
+ coverage report --include=./**/stock_package_shipping_sendcloud/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_package_shipping_sendcloud/tryton.cfg b/modules/stock_package_shipping_sendcloud/tryton.cfg
new file mode 100644
index 0000000000..45755573e2
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/tryton.cfg
@@ -0,0 +1,16 @@
+[tryton]
+version=6.7.0
+depends:
+ carrier
+ company
+ ir
+ party
+ product
+ stock
+ stock_shipment_measurements
+ stock_package
+ stock_package_shipping
+xml:
+ carrier.xml
+ stock.xml
+ message.xml
diff --git a/modules/stock_package_shipping_sendcloud/view/carrier_address_form.xml b/modules/stock_package_shipping_sendcloud/view/carrier_address_form.xml
new file mode 100644
index 0000000000..4d069bfee5
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/view/carrier_address_form.xml
@@ -0,0 +1,14 @@
+
+
+
diff --git a/modules/stock_package_shipping_sendcloud/view/carrier_address_list.xml b/modules/stock_package_shipping_sendcloud/view/carrier_address_list.xml
new file mode 100644
index 0000000000..b6aa131065
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/view/carrier_address_list.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping_sendcloud/view/carrier_form.xml b/modules/stock_package_shipping_sendcloud/view/carrier_form.xml
new file mode 100644
index 0000000000..b3c02654bc
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/view/carrier_form.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping_sendcloud/view/carrier_shipping_method_form.xml b/modules/stock_package_shipping_sendcloud/view/carrier_shipping_method_form.xml
new file mode 100644
index 0000000000..76d121a722
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/view/carrier_shipping_method_form.xml
@@ -0,0 +1,14 @@
+
+
+
diff --git a/modules/stock_package_shipping_sendcloud/view/carrier_shipping_method_list.xml b/modules/stock_package_shipping_sendcloud/view/carrier_shipping_method_list.xml
new file mode 100644
index 0000000000..700ca8290a
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/view/carrier_shipping_method_list.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping_sendcloud/view/credential_form.xml b/modules/stock_package_shipping_sendcloud/view/credential_form.xml
new file mode 100644
index 0000000000..14b81cf805
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/view/credential_form.xml
@@ -0,0 +1,18 @@
+
+
+
diff --git a/modules/stock_package_shipping_sendcloud/view/credential_list.xml b/modules/stock_package_shipping_sendcloud/view/credential_list.xml
new file mode 100644
index 0000000000..b0563b8f28
--- /dev/null
+++ b/modules/stock_package_shipping_sendcloud/view/credential_list.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping_ups/.drone.yml b/modules/stock_package_shipping_ups/.drone.yml
new file mode 100644
index 0000000000..2a43179527
--- /dev/null
+++ b/modules/stock_package_shipping_ups/.drone.yml
@@ -0,0 +1,71 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID UPS_USER_ID UPS_PASSWORD UPS_LICENSE UPS_ACCOUNT_NUMBER
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ secrets: [ ups_user_id, ups_password, ups_account_number, ups_license ]
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_package_shipping_ups/.flake8 b/modules/stock_package_shipping_ups/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_package_shipping_ups/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_package_shipping_ups/.isort.cfg b/modules/stock_package_shipping_ups/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_package_shipping_ups/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_package_shipping_ups/CHANGELOG b/modules/stock_package_shipping_ups/CHANGELOG
new file mode 100644
index 0000000000..bb7a7ec6d3
--- /dev/null
+++ b/modules/stock_package_shipping_ups/CHANGELOG
@@ -0,0 +1,47 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Use contact mechanism from address
+* Update service types
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add notification service option
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+* Use total weight of package
+
+Version 4.2.0 - 2016-11-28
+* Initial release
diff --git a/modules/stock_package_shipping_ups/COPYRIGHT b/modules/stock_package_shipping_ups/COPYRIGHT
new file mode 100644
index 0000000000..1a03f5236a
--- /dev/null
+++ b/modules/stock_package_shipping_ups/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2016-2022 B2CK.
+Copyright (C) 2016-2022 Nicolas Évrard.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_package_shipping_ups/LICENSE b/modules/stock_package_shipping_ups/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_package_shipping_ups/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_package_shipping_ups/MANIFEST.in b/modules/stock_package_shipping_ups/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_package_shipping_ups/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_package_shipping_ups/README.rst b/modules/stock_package_shipping_ups/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_package_shipping_ups/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_package_shipping_ups/__init__.py b/modules/stock_package_shipping_ups/__init__.py
new file mode 100644
index 0000000000..9e8d4a2292
--- /dev/null
+++ b/modules/stock_package_shipping_ups/__init__.py
@@ -0,0 +1,21 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import carrier, stock
+
+
+def register():
+ Pool.register(
+ stock.PackageType,
+ stock.Package,
+ stock.ShipmentOut,
+ stock.ShipmentInReturn,
+ carrier.CredentialUPS,
+ carrier.Carrier,
+ module='stock_package_shipping_ups', type_='model')
+ Pool.register(
+ stock.CreateShipping,
+ stock.CreateShippingUPS,
+ module='stock_package_shipping_ups', type_='wizard')
diff --git a/modules/stock_package_shipping_ups/carrier.py b/modules/stock_package_shipping_ups/carrier.py
new file mode 100644
index 0000000000..713ed9c5bd
--- /dev/null
+++ b/modules/stock_package_shipping_ups/carrier.py
@@ -0,0 +1,127 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.model import (
+ MatchMixin, ModelSQL, ModelView, fields, sequence_ordered)
+from trytond.pool import PoolMeta
+from trytond.pyson import Eval
+
+
+class CredentialUPS(sequence_ordered(), ModelSQL, ModelView, MatchMixin):
+ 'UPS Credential'
+ __name__ = 'carrier.credential.ups'
+
+ company = fields.Many2One('company.company', 'Company')
+ user_id = fields.Char('User ID', required=True)
+ password = fields.Char('Password', required=True)
+ license = fields.Char('License', required=True)
+ account_number = fields.Char('Account Number', required=True)
+ use_metric = fields.Boolean('Use Metric')
+ server = fields.Selection([
+ ('testing', 'Testing'),
+ ('production', 'Production'),
+ ], 'Server')
+
+ @classmethod
+ def default_use_metric(cls):
+ return True
+
+ @classmethod
+ def default_server(cls):
+ return 'testing'
+
+
+class Carrier(metaclass=PoolMeta):
+ __name__ = 'carrier'
+
+ ups_service_type = fields.Selection([
+ (None, ''),
+ ('01', 'Next Day Air'),
+ ('02', '2nd Day Air'),
+ ('03', 'Ground'),
+ ('07', 'Express'),
+ ('08', 'Expedited'),
+ ('11', 'UPS Standard'),
+ ('12', '3 Days Select'),
+ ('13', 'Next Day Air Saver'),
+ ('14', 'UPS Next Day Air Early'),
+ ('17', "UPS Worldwide Economy DDU"),
+ ('54', 'Express Plus'),
+ ('59', '2nd Day Air A.M.'),
+ ('65', 'UPS Saver'),
+ ('M2', 'First Class Mail'),
+ ('M3', 'Priority Mail'),
+ ('M4', 'Expedited Mail Innovations'),
+ ('M5', 'Priority Mail Innovations'),
+ ('M6', 'Economy Mail Innovations'),
+ ('M7', "Mail Innovations (MI) Returns"),
+ ('70', 'UPS Access Point Economy'),
+ ('71', "UPS Worldwide Express Freight Midday"),
+ ('72', "UPS Worldwide Economy DDP"),
+ ('74', "UPS Express 12:00"),
+ ('82', 'UPS Today Standard'),
+ ('83', 'UPS Today Dedicated Courier'),
+ ('84', 'UPS Today Intercity'),
+ ('85', 'UPS Today Express'),
+ ('86', 'UPS Today Express Saver'),
+ ('96', 'UPS Worldwide Express Freight'),
+ ], 'Service Type', sort=False, translate=False,
+ states={
+ 'required': Eval('shipping_service') == 'ups',
+ 'invisible': Eval('shipping_service') != 'ups',
+ })
+ ups_label_image_format = fields.Selection([
+ (None, ''),
+ ('EPL', 'EPL2'),
+ ('SPL', 'SPL'),
+ ('ZPL', 'ZPL'),
+ ('GIF', 'GIF'),
+ ('STARPL', 'Star Printer'),
+ ], 'Label Image Format', sort=False, translate=False,
+ states={
+ 'required': Eval('shipping_service') == 'ups',
+ 'invisible': Eval('shipping_service') != 'ups',
+ })
+ ups_label_height = fields.Selection([
+ (None, ''),
+ ('6', '6'),
+ ('8', '8'),
+ ], 'Label Height', sort=False, translate=False,
+ states={
+ 'required': ((Eval('shipping_service') == 'ups')
+ & (Eval('ups_label_image_format') != 'GIF')),
+ 'invisible': ((Eval('shipping_service') != 'ups')
+ | (Eval('ups_label_image_format') == 'GIF')),
+ })
+ ups_notifications = fields.MultiSelection([
+ ('5', "Quantum View In-transit"),
+ ('6', "Quantum View Shop"),
+ ('7', "Quantum View Exception"),
+ ('8', "Quantum View Delivery"),
+ ('2', "Return or Label Creation"),
+ ('012', "Alternate Delivery Location"),
+ ('013', "UPS Access Point Shipper"),
+ ], "Notifications", sort=False,
+ states={
+ 'invisible': Eval('shipping_service') != 'ups',
+ })
+
+ @classmethod
+ def __setup__(cls):
+ super(Carrier, cls).__setup__()
+ cls.shipping_service.selection.append(('ups', 'UPS'))
+
+ @classmethod
+ def view_attributes(cls):
+ return super(Carrier, cls).view_attributes() + [
+ ("/form/separator[@id='ups']", 'states', {
+ 'invisible': Eval('shipping_service') != 'ups',
+ }),
+ ]
+
+ @property
+ def shipping_label_mimetype(self):
+ mimetype = super().shipping_label_mimetype
+ if self.shipping_service == 'ups':
+ if self.ups_label_image_format == 'GIF':
+ mimetype = 'image/gif'
+ return mimetype
diff --git a/modules/stock_package_shipping_ups/carrier.xml b/modules/stock_package_shipping_ups/carrier.xml
new file mode 100644
index 0000000000..fe220da04e
--- /dev/null
+++ b/modules/stock_package_shipping_ups/carrier.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+ carrier
+
+ carrier_form
+
+
+
+ carrier.credential.ups
+ form
+ ups_credential_form
+
+
+ carrier.credential.ups
+ tree
+ ups_credential_list
+
+
+
+ UPS Credentials
+ carrier.credential.ups
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping_ups/doc/index.rst b/modules/stock_package_shipping_ups/doc/index.rst
new file mode 100644
index 0000000000..07eb9ce7ae
--- /dev/null
+++ b/modules/stock_package_shipping_ups/doc/index.rst
@@ -0,0 +1,41 @@
+Stock Package Shipping UPS Module
+#################################
+
+The Stock Package Shipping UPS module allows you to generate the UPS labels per
+package using the UPS webservices.
+
+The credential for the webservice is specified by the following fields:
+
+UPS Carrier Credential
+**********************
+
+This model allows to define the credential used to connect the UPS API.
+The credentials used to connect to the UPS API will be automatically retrieved
+based on the company of the Shipment.
+
+- *Company*: The company for which those credentials are valid
+- *User ID*: The User ID provided by UPS.
+- *Password*: The Password used to access the MyUPS Portal.
+- *Account Number*: The account number UPS assigned to you when you requested the
+ API credentials (also known as the Shipper Number).
+- *License*: The License number UPS assigned to you when you requested the API
+ credentials
+- *Server*: Are those credentials used for accessing the Testing or the
+ Production server of UPS.
+- *Use Metric*: Use Metric units when communicating with the UPS webservice.
+
+Carrier
+*******
+
+The Carrier model is extended with the following fields:
+
+- *Service Type*: The UPS service type requested
+- *Label Image Format*: The Image Format used for the label sent by UPS
+- *Label Image Height*: The Height of the label sent by UPS.
+
+Package Type
+************
+
+The Package Type model is extended with the following field:
+
+- *UPS Code*: The UPS Code of the package.
diff --git a/modules/stock_package_shipping_ups/exceptions.py b/modules/stock_package_shipping_ups/exceptions.py
new file mode 100644
index 0000000000..5ef681f84d
--- /dev/null
+++ b/modules/stock_package_shipping_ups/exceptions.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.exceptions import UserError
+
+
+class UPSError(UserError):
+ pass
diff --git a/modules/stock_package_shipping_ups/locale/bg.po b/modules/stock_package_shipping_ups/locale/bg.po
new file mode 100644
index 0000000000..60a2d30933
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/bg.po
@@ -0,0 +1,154 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr ""
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr ""
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Фирма"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "Парола"
+
+#, fuzzy
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr "Сървър"
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Create UPS Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr "Управление на производство"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr ""
diff --git a/modules/stock_package_shipping_ups/locale/ca.po b/modules/stock_package_shipping_ups/locale/ca.po
new file mode 100644
index 0000000000..b7420d8e90
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/ca.po
@@ -0,0 +1,159 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr "Alçada de l'etiqueta"
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr "Format de la imatge de l'etiqueta"
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr "Notificacions"
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr "Tipus de servei"
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr "Número de compte"
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr "Llicència"
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "Contrasenya"
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr "Servidor"
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr "Usa mètric"
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr "Identificador usuari"
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr "Codi UPS"
+
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "Credencial UPS"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Crea enviament UPS per paquets"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "Credencials UPS"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+"Per a validar l'albarà \"%(shipment)s\" s'ha d'afegir un número de telèfon a"
+" l'adreça \"%(address)s\"."
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+"No podeu crear el enviament per l'albarà \"%(shipment)s\" perquè ja té un "
+"número de referència."
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+"Per validar l'albarà \"%(shipment)s\" heu d'emplenar la seva descripció "
+"d'enviament."
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"La crida al servei web UPS ha fallat amb el següent missatge d'error:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+"Per validar l'albarà \"%(shipment)s\" heu d'establir una adreça al magatzem "
+"\"%(warehouse)s\"."
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "Credencials UPS"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr "Direcció d'enviament alternativa"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr "Lliurament"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr "Excepció"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr "En trànsit"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr "Tenda"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr "Creació de devolució o etiqueta"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr "UPS Punt d'accés de transportista"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr "Producció"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr "Proves"
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr "Informació de les credencials"
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr "UPS"
diff --git a/modules/stock_package_shipping_ups/locale/cs.po b/modules/stock_package_shipping_ups/locale/cs.po
new file mode 100644
index 0000000000..04ef9b2f2a
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/cs.po
@@ -0,0 +1,150 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr ""
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr ""
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Create UPS Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr ""
diff --git a/modules/stock_package_shipping_ups/locale/de.po b/modules/stock_package_shipping_ups/locale/de.po
new file mode 100644
index 0000000000..650cb318a4
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/de.po
@@ -0,0 +1,159 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr "Höhe Etikett"
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr "Bildformat Etikett"
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr "Benachrichtigungen"
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr "Dienstleistungstyp"
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr "Kontonummer"
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Unternehmen"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr "Lizenz"
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "Passwort"
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr "Server"
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr "Metrische Einheiten verwenden"
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr "Benutzer ID"
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr "UPS Code"
+
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "UPS Anmeldedaten"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "UPS Versand für Pakete erstellen"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Anmeldedaten"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+"Um die Lieferung \"%(shipment)s\" validieren zu können muss eine "
+"Telefonnummer für die Adresse \"%(address)s\" erfasst werden."
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+"Für die Lieferung \"%(shipment)s\" kann keine Sendung erstellt werden, da "
+"sie bereits eine Referenznummer hat."
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+"Um die Lieferung \"%(shipment)s\" validieren zu können, muss deren "
+"Versandbeschreibung ausgefüllt werden."
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"Der Aufruf des UPS-Webservice schlug fehl mit der folgenden Fehlermeldung:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+"Damit die Lieferung \"%(shipment)s\" validiert werden kann, muss eine "
+"Adresse für den Logistikstandort \"%(warehouse)s\" erfasst werden."
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Anmeldedaten"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr "Alternativer Zustellungsort"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr "Quantum View Lieferung"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr "Quantum View Ausnahme"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr "Quantum View Unterwegs"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr "Quantum View Shop"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr "Versandettikett erstellt"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr "An UPS übergeben"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr "Produktivumgebung"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr "Testumgebung"
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr "Anmeldedaten"
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr "UPS"
diff --git a/modules/stock_package_shipping_ups/locale/es.po b/modules/stock_package_shipping_ups/locale/es.po
new file mode 100644
index 0000000000..1b72b7b0dd
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/es.po
@@ -0,0 +1,159 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr "Altura de la etiqueta"
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr "Formato de la imagen de la etiqueta"
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr "Notificaciones"
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr "Tipo de servicio"
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr "Número de cuenta"
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr "Licencia"
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "Contraseña"
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr "Servidor"
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr "Usar sistema métrico"
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr "Identificador usuario"
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr "Código UPS"
+
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "Credencial UPS"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Crear envíos UPS para paquetes"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "Credenciales UPS"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+"Para validar el albarán \"%(shipment)s\" debes añadir un numero de teléfono "
+"a la dirección \"%(address)s\"."
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+"No puede crear el envío para el albarán \"%(shipment)s\" porque ya tiene un "
+"número de referencia."
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+"Para validar el albaran \"%(shipment)s\" debe llenar la descripción de "
+"envío."
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"La llamada al servicio web UPS ha fallado con el siguiente mensaje de error:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+"Para validar el albarán \"%(shipment)s\" debe establecer una dirección en el"
+" almacén \"%(warehouse)s\"."
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "Credenciales UPS"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr "Dirección de envío alternativa"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr "Entrega"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr "Excepción"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr "En tránsito"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr "Tienda"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr "Creación de devolución o etiqueta"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr "UPS Punto de acceso de transportista"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr "Producción"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr "Pruebas"
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr "Información de las credenciales"
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr "UPS"
diff --git a/modules/stock_package_shipping_ups/locale/es_419.po b/modules/stock_package_shipping_ups/locale/es_419.po
new file mode 100644
index 0000000000..009244e4fc
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/es_419.po
@@ -0,0 +1,149 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr ""
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr ""
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr "Identificador de usuario"
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr ""
+
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr ""
diff --git a/modules/stock_package_shipping_ups/locale/et.po b/modules/stock_package_shipping_ups/locale/et.po
new file mode 100644
index 0000000000..8cb6f7709a
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/et.po
@@ -0,0 +1,149 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr "Etiketi kõrgus"
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr "Etiketi pildi formaat"
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr "Teenuse tüüp"
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr "Konto number"
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Ettevõte"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr "Litsents"
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "Salasõna"
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr "Server"
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr "Kasutaja ID"
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr "UPS kood"
+
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "UPS viide"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS viide"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPSviide"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr "Tootmine"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr "Testimine"
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr "UPS"
diff --git a/modules/stock_package_shipping_ups/locale/fa.po b/modules/stock_package_shipping_ups/locale/fa.po
new file mode 100644
index 0000000000..4bdb152f31
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/fa.po
@@ -0,0 +1,161 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr "ارتفاع برچسب"
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr "فرمت تصویر برچسب"
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr "نوع خدمات"
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr "شماره حساب"
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "شرکت"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr "لایسنس"
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "کلمه عبور"
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr "سرور"
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr "استفاده از متریک"
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr "شناسه کاربر"
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr "کد سرویس UPS"
+
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "گواهی نامه UPS"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "ایجاد حمل ونقل UPS برای بسته ها"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "گواهی نامه UPS"
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+"برای تأیید حمل و نقل :\"%(shipment)s\" شما باید شماره تلفن را به نهاد/سازمان"
+" :\"%(party)s\" اضافه کنید."
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+"شما نمی توانید حمل را برای حمل و نقل :\"%(shipment)s\" ایجاد کنید، چراکه "
+"دارای یک شماره مرجع است."
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+"برای تایید حمل و نقل :\"%(shipment)s\" شما باید توضیحات حمل و نقل خود را پر "
+"کنید."
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"تماس با وب سرویس UPS با پیغام خطای زیر انجام نشد :\n"
+"\"%s\""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+"برای تأیید حمل و نقل :\"%(shipment)s\" شما باید آدرس را در "
+"انبار:\"%(warehouse)s\" قرار دهید."
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "گواهی نامه های UPS"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr "تهیه کننده"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr "آزمایش"
+
+#, fuzzy
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr "اطلاعات گواهی نامه"
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr "UPS"
diff --git a/modules/stock_package_shipping_ups/locale/fi.po b/modules/stock_package_shipping_ups/locale/fi.po
new file mode 100644
index 0000000000..04ef9b2f2a
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/fi.po
@@ -0,0 +1,150 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr ""
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr ""
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Create UPS Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr ""
diff --git a/modules/stock_package_shipping_ups/locale/fr.po b/modules/stock_package_shipping_ups/locale/fr.po
new file mode 100644
index 0000000000..c46c5b16e0
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/fr.po
@@ -0,0 +1,159 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr "Hauteur d'étiquette"
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr "Format de l'image d'étiquette"
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr "Notifications"
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr "Type de service"
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr "Numéro de compte"
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Société"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr "Licence"
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "Mot de passe"
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr "Serveur"
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr "Utiliser le système métrique"
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr "ID d'utilisateur"
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr "Code UPS"
+
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "Identifiant UPS"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Créer la livraison UPS pour les emballages"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "Identifiant UPS"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+"Pour valider l'expédition « %(shipment)s », vous devez ajouter un numéro de "
+"téléphone pour l'adresse « %(address)s »."
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+"Vous ne pouvez pas créer de livraison pour l'expédition « %(shipment)s » car"
+" elle a déjà un numéro de référence."
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+"Pour valider l'expédition « %(shipment)s », vous devez remplir sa "
+"description de livraison."
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"L'appel au web service UPS a échoué avec le message d'erreur :\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+"Pour validé l'expédition « %(shipment)s », vous devez définir une adresse "
+"pour l'entrepôt « %(warehouse)s »."
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "Identifiants UPS"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr "Lieu de livraison alternatif"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr "Livraison Quantum View"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr "Exception Quantum View"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr "En transit Quantum View"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr "Boutique Quantum View"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr "Retour ou création d'étiquette"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr "Point d'accès UPS expéditeur"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr "Essai"
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr "Informations d'identification"
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr "UPS"
diff --git a/modules/stock_package_shipping_ups/locale/hu.po b/modules/stock_package_shipping_ups/locale/hu.po
new file mode 100644
index 0000000000..d0a2893628
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/hu.po
@@ -0,0 +1,153 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr ""
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr ""
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Társaság"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "Jelszó"
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Create UPS Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr "Termelés"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr ""
diff --git a/modules/stock_package_shipping_ups/locale/id.po b/modules/stock_package_shipping_ups/locale/id.po
new file mode 100644
index 0000000000..9f14695122
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/id.po
@@ -0,0 +1,149 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr ""
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr ""
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Perusahaan"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr "Lisensi"
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "Kata sandi"
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr "Server"
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr ""
+
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr "Produksi"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr "Testing"
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr ""
diff --git a/modules/stock_package_shipping_ups/locale/it.po b/modules/stock_package_shipping_ups/locale/it.po
new file mode 100644
index 0000000000..b34ee9cb8c
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/it.po
@@ -0,0 +1,152 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr ""
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr ""
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr "Numero del conto"
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Azienda"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "Password"
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Create UPS Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr ""
diff --git a/modules/stock_package_shipping_ups/locale/lo.po b/modules/stock_package_shipping_ups/locale/lo.po
new file mode 100644
index 0000000000..d2ec522556
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/lo.po
@@ -0,0 +1,152 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr ""
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr ""
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "ຫ້ອງການ/ສຳນັກງານ"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Create UPS Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr "ຜະລິດຕະພັນ"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr ""
diff --git a/modules/stock_package_shipping_ups/locale/lt.po b/modules/stock_package_shipping_ups/locale/lt.po
new file mode 100644
index 0000000000..26d2c6196a
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/lt.po
@@ -0,0 +1,150 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr ""
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr ""
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Organizacija"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr "Naudotojo ID"
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Create UPS Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr ""
diff --git a/modules/stock_package_shipping_ups/locale/nl.po b/modules/stock_package_shipping_ups/locale/nl.po
new file mode 100644
index 0000000000..55c387b0f7
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/nl.po
@@ -0,0 +1,159 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr "Label hoogte"
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr "Label afbeeldingsformaat"
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr "Notificaties"
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr "Soort Dienst"
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr "Rekeningnummer"
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Bedrijf"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr "Licentie"
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "Wachtwoord"
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr "Server"
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr "Gebruik metrische eenheden"
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr "Gebruiker ID"
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr "UPS-code"
+
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "UPS-gegevens"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Maak een UPS-verzending voor de pakketten"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS aanmeldgegevens"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+"Om zending \"%(shipment)s\" te valideren, moet u een telefoonnummer "
+"toevoegen aan adres \"%(address)s\"."
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+"U kunt geen verzending voor zending \"%(shipment)s\" maken omdat deze al een"
+" referentienummer heeft."
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+"Om verzending \"%(shipment)s\" te valideren, moet u de verzendomschrijving "
+"invullen."
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"UPS webservice-oproep is mislukt met het volgende foutbericht:\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+"Om zending \"%(shipment)s\" te valideren, moet u een adres voor magazijn "
+"\"%(warehouse)s\" instellen."
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS aanmeldgegevens"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr "Alternatieve aflever locatie"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr "Quantum weergave aflevering"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr "Quantum weergave uitzondering"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr "Quantum weergave onderweg"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr "Quantum weergave winkel"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr "Retourneren of label aanmaken"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr "UPS Access Point verzender"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr "Productie"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr "Testen"
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr "Aanmeld gegevens"
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr "UPS"
diff --git a/modules/stock_package_shipping_ups/locale/pl.po b/modules/stock_package_shipping_ups/locale/pl.po
new file mode 100644
index 0000000000..1a1ce2df54
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/pl.po
@@ -0,0 +1,152 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr ""
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr ""
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr "Typ usługi"
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr "Numer konta"
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Firma"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr "Licencja"
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "Hasło"
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr "Serwer"
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr "ID użytkownika"
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr "Kod UPS"
+
+#, fuzzy
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Create UPS Shipping for Packages"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr "Produkcja"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr "UPS"
diff --git a/modules/stock_package_shipping_ups/locale/pt.po b/modules/stock_package_shipping_ups/locale/pt.po
new file mode 100644
index 0000000000..0062f92775
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/pt.po
@@ -0,0 +1,157 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr "Altura da Etiqueta"
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr "Formato da Imagem da Etiqueta"
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr "Tipo de serviço"
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr "Número da Conta"
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr "Licença"
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "Senha"
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr "Servidor"
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr "Usar Métrica"
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr "ID de usuário"
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr "Código UPS"
+
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "Credencial UPS"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Create UPS Shipping for Packages"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"A chamada ao serviço web UPS falhou com a seguinte mensagem:\n"
+"\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr "Produção"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr "Testando"
+
+#, fuzzy
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr "Informações da Credencial"
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr "UPS"
diff --git a/modules/stock_package_shipping_ups/locale/ro.po b/modules/stock_package_shipping_ups/locale/ro.po
new file mode 100644
index 0000000000..1146861b29
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/ro.po
@@ -0,0 +1,154 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr ""
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr ""
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Companie"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr ""
+
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+"Pentru a valida expedierea \"%(shipment)s\" trebuie setata o adresa la "
+"depozit \"%(warehouse)s\"."
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+"Pentru a valida expedierea \"%(shipment)s\" trebuie setata o adresa la "
+"depozit \"%(warehouse)s\"."
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr ""
diff --git a/modules/stock_package_shipping_ups/locale/ru.po b/modules/stock_package_shipping_ups/locale/ru.po
new file mode 100644
index 0000000000..185b3de104
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/ru.po
@@ -0,0 +1,154 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr ""
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr ""
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Учет.орг."
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "Пароль"
+
+#, fuzzy
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr "Сервер"
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Create UPS Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr "Производство"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr ""
diff --git a/modules/stock_package_shipping_ups/locale/sl.po b/modules/stock_package_shipping_ups/locale/sl.po
new file mode 100644
index 0000000000..439e5a3f85
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/sl.po
@@ -0,0 +1,157 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr "Velikost nalepke"
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr "Format nalepke"
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr "Vrsta storitve"
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr "Številka računa"
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr "Družba"
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr "Dovoljenje"
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "Geslo"
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr "Strežnik"
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr "Metrični sistem"
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr "Uporabnikov ID"
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr "UPS Šifra"
+
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "UPS prijava"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Create UPS Shipping for Packages"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+"Sporočilo napake pri klicu UPS spletne storitve:\n"
+"\n"
+"%(message)s"
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr "Produkcijski"
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr "Preizkusni"
+
+#, fuzzy
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr "Prijava"
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr "UPS"
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr "UPS"
diff --git a/modules/stock_package_shipping_ups/locale/tr.po b/modules/stock_package_shipping_ups/locale/tr.po
new file mode 100644
index 0000000000..04ef9b2f2a
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/tr.po
@@ -0,0 +1,150 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr ""
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr ""
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Create UPS Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr ""
diff --git a/modules/stock_package_shipping_ups/locale/uk.po b/modules/stock_package_shipping_ups/locale/uk.po
new file mode 100644
index 0000000000..d59ec9b353
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/uk.po
@@ -0,0 +1,149 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr ""
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr ""
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr ""
+
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr ""
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr ""
diff --git a/modules/stock_package_shipping_ups/locale/zh_CN.po b/modules/stock_package_shipping_ups/locale/zh_CN.po
new file mode 100644
index 0000000000..e8fde8c231
--- /dev/null
+++ b/modules/stock_package_shipping_ups/locale/zh_CN.po
@@ -0,0 +1,151 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,ups_label_height:"
+msgid "Label Height"
+msgstr ""
+
+msgctxt "field:carrier,ups_label_image_format:"
+msgid "Label Image Format"
+msgstr ""
+
+msgctxt "field:carrier,ups_notifications:"
+msgid "Notifications"
+msgstr ""
+
+msgctxt "field:carrier,ups_service_type:"
+msgid "Service Type"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,account_number:"
+msgid "Account Number"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,license:"
+msgid "License"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:carrier.credential.ups,password:"
+msgid "Password"
+msgstr "密码"
+
+msgctxt "field:carrier.credential.ups,server:"
+msgid "Server"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,use_metric:"
+msgid "Use Metric"
+msgstr ""
+
+msgctxt "field:carrier.credential.ups,user_id:"
+msgid "User ID"
+msgstr ""
+
+msgctxt "field:stock.package.type,ups_code:"
+msgid "UPS Code"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:carrier.credential.ups,name:"
+msgid "UPS Credential"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.action,name:act_create_shipping_ups_wizard"
+msgid "Create UPS Shipping for Packages"
+msgstr "Create UPS Shipping for Packages"
+
+msgctxt "model:ir.action,name:act_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "model:ir.message,text:msg_phone_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must add phone number for address "
+"\"%(address)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipment_has_reference_number"
+msgid ""
+"You cannot create shipping for shipment \"%(shipment)s\" because it has "
+"already a reference number."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shipping_description_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must fill its shipping "
+"description."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_ups_webservice_error"
+msgid ""
+"UPS webservice call failed with the following error message:\n"
+"%(message)s"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_warehouse_address_required"
+msgid ""
+"To validate shipment \"%(shipment)s\" you must set an address on warehouse "
+"\"%(warehouse)s\"."
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_ups_credential_form"
+msgid "UPS Credentials"
+msgstr "UPS Credentials"
+
+msgctxt "selection:carrier,shipping_service:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Alternate Delivery Location"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Delivery"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Exception"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View In-transit"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Quantum View Shop"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "Return or Label Creation"
+msgstr ""
+
+msgctxt "selection:carrier,ups_notifications:"
+msgid "UPS Access Point Shipper"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Production"
+msgstr ""
+
+msgctxt "selection:carrier.credential.ups,server:"
+msgid "Testing"
+msgstr ""
+
+msgctxt "view:carrier.credential.ups:"
+msgid "Credential Information"
+msgstr ""
+
+msgctxt "view:carrier:"
+msgid "UPS"
+msgstr ""
+
+msgctxt "view:stock.package.type:"
+msgid "UPS"
+msgstr ""
diff --git a/modules/stock_package_shipping_ups/message.xml b/modules/stock_package_shipping_ups/message.xml
new file mode 100644
index 0000000000..2bb8d0487c
--- /dev/null
+++ b/modules/stock_package_shipping_ups/message.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+ UPS webservice call failed with the following error message:
+%(message)s
+
+
+ To validate shipment "%(shipment)s" you must set an address on warehouse "%(warehouse)s".
+
+
+ To validate shipment "%(shipment)s" you must add phone number for address "%(address)s".
+
+
+ To validate shipment "%(shipment)s" you must fill its shipping description.
+
+
+ You cannot create shipping for shipment "%(shipment)s" because it has already a reference number.
+
+
+
diff --git a/modules/stock_package_shipping_ups/setup.py b/modules/stock_package_shipping_ups/setup.py
new file mode 100755
index 0000000000..8204a22076
--- /dev/null
+++ b/modules/stock_package_shipping_ups/setup.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_package_shipping_ups'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = ['requests']
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [
+ get_require_version('proteus'),
+ get_require_version('trytond_sale'),
+ get_require_version('trytond_sale_shipment_cost'),
+ ]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='UPS connector for the Tryton application platform',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": (
+ 'https://hg.tryton.org/modules/stock_package_shipping_ups'),
+ },
+ keywords='tryton stock package shipping ups',
+ package_dir={'trytond.modules.stock_package_shipping_ups': '.'},
+ packages=(
+ ['trytond.modules.stock_package_shipping_ups']
+ + ['trytond.modules.stock_package_shipping_ups.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_package_shipping_ups': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_package_shipping_ups = trytond.modules.stock_package_shipping_ups
+ """,
+ )
diff --git a/modules/stock_package_shipping_ups/stock.py b/modules/stock_package_shipping_ups/stock.py
new file mode 100644
index 0000000000..5418dde100
--- /dev/null
+++ b/modules/stock_package_shipping_ups/stock.py
@@ -0,0 +1,422 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import base64
+import re
+import ssl
+import urllib.parse
+from itertools import zip_longest
+
+import requests
+
+from trytond.config import config
+from trytond.i18n import gettext
+from trytond.model import fields
+from trytond.model.exceptions import AccessError
+from trytond.modules.stock_package_shipping.exceptions import (
+ PackingValidationError)
+from trytond.pool import Pool, PoolMeta
+from trytond.transaction import Transaction
+from trytond.wizard import StateAction, StateTransition, Wizard
+
+from .exceptions import UPSError
+
+SERVER_URLS = {
+ 'testing': 'https://wwwcie.ups.com/json/Ship',
+ 'production': 'https://onlinetools.ups.com/json/Ship',
+ }
+TRACKING_URL = 'https://www.ups.com/track'
+TIMEOUT = config.getfloat(
+ 'stock_package_shipping_ups', 'requests_timeout', default=300)
+
+
+class PackageType(metaclass=PoolMeta):
+ __name__ = 'stock.package.type'
+
+ ups_code = fields.Selection([
+ (None, ''),
+ ('01', 'UPS Letter'),
+ ('02', 'Customer Supplied Package'),
+ ('03', 'Tube'),
+ ('04', 'PAK'),
+ ('21', 'UPS Express Box'),
+ ('24', 'UPS 25KG Box'),
+ ('25', 'UPS 10KG Box'),
+ ('30', 'Pallet'),
+ ('2a', 'Small Express Box'),
+ ('2b', 'Medium Express Box'),
+ ('2c', 'Large Express Box'),
+ ('56', 'Flats'),
+ ('57', 'Parcels'),
+ ('58', 'BPM'),
+ ('59', 'First Class'),
+ ('60', 'Priority'),
+ ('61', 'Machinables'),
+ ('62', 'Irregulars'),
+ ('63', 'Parcel Post'),
+ ('64', 'BPM Parcel'),
+ ('65', 'Media Mail'),
+ ('66', 'BPM Flat'),
+ ('67', 'Standard Flat'),
+ ], 'UPS Code', sort=False, translate=False)
+
+ @classmethod
+ def default_ups_code(cls):
+ return None
+
+
+class Package(metaclass=PoolMeta):
+ __name__ = 'stock.package'
+
+ def get_shipping_tracking_url(self, name):
+ pool = Pool()
+ ShipmentOut = pool.get('stock.shipment.out')
+ ShipmentInReturn = pool.get('stock.shipment.in.return')
+ url = super().get_shipping_tracking_url(name)
+ if (self.shipping_reference
+ and self.shipment
+ and self.shipment.id >= 0
+ and self.shipment.carrier
+ and self.shipment.carrier.shipping_service == 'ups'):
+ party = address = None
+ if isinstance(self.shipment, ShipmentOut):
+ party = self.shipment.customer
+ address = self.shipment.delivery_address
+ elif isinstance(self.shipment, ShipmentInReturn):
+ party = self.shipment.supplier
+ address = self.shipment.delivery_address
+ parts = urllib.parse.urlsplit(TRACKING_URL)
+ query = urllib.parse.parse_qsl(parts.query)
+ if party and party.lang and address and address.country:
+ loc = '_'.join(
+ (party.lang.code.split('_')[0], address.country.code))
+ query.append(('loc', loc))
+ query.append(('tracknum', self.shipping_reference))
+ parts = list(parts)
+ parts[3] = urllib.parse.urlencode(query)
+ url = urllib.parse.urlunsplit(parts)
+ return url
+
+
+class ShippingUPSMixin:
+ __slots__ = ()
+
+ def validate_packing_ups(self, usage=None):
+ warehouse = self.shipping_warehouse
+ if not warehouse.address:
+ raise PackingValidationError(
+ gettext('stock_package_shipping_ups'
+ '.msg_warehouse_address_required',
+ shipment=self.rec_name,
+ warehouse=warehouse.rec_name))
+ if warehouse.address.country != self.delivery_address.country:
+ for address in [self.shipping_to_address, warehouse.address]:
+ if not address.contact_mechanism_get(
+ {'phone', 'mobile'}, usage=usage):
+ raise PackingValidationError(
+ gettext('stock_package_shipping_ups'
+ '.msg_phone_required',
+ shipment=self.rec_name,
+ address=address.rec_name))
+ if not self.shipping_description:
+ if (any(p.type.ups_code != '01' for p in self.root_packages)
+ and self.carrier.ups_service_type != '11'):
+ # TODO Should also test if a country is not in the EU
+ raise PackingValidationError(
+ gettext('stock_package_shipping_ups'
+ '.msg_shipping_description_required',
+ shipment=self.rec_name))
+
+
+class ShipmentOut(ShippingUPSMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out'
+
+
+class ShipmentInReturn(ShippingUPSMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in.return'
+
+
+class CreateShipping(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.create_shipping'
+
+ ups = StateAction(
+ 'stock_package_shipping_ups.act_create_shipping_ups_wizard')
+
+ def transition_start(self):
+ next_state = super(CreateShipping, self).transition_start()
+ if self.record.carrier.shipping_service == 'ups':
+ next_state = 'ups'
+ return next_state
+
+ def do_ups(self, action):
+ ctx = Transaction().context
+ return action, {
+ 'model': ctx['active_model'],
+ 'id': ctx['active_id'],
+ 'ids': [ctx['active_id']],
+ }
+
+
+class CreateShippingUPS(Wizard):
+ 'Create UPS Shipping'
+ __name__ = 'stock.shipment.create_shipping.ups'
+
+ start = StateTransition()
+
+ def transition_start(self):
+ pool = Pool()
+ Package = pool.get('stock.package')
+
+ shipment = self.record
+ if shipment.reference:
+ raise AccessError(
+ gettext('stock_package_shipping_ups'
+ '.msg_shipment_has_reference_number',
+ shipment=shipment.rec_name))
+
+ credential = self.get_credential(shipment)
+ carrier = shipment.carrier
+ packages = shipment.root_packages
+ shipment_request = self.get_request(shipment, packages, credential)
+ api_url = config.get('stock_package_shipping_ups', credential.server,
+ default=SERVER_URLS[credential.server])
+ nb_tries, response = 0, None
+ error_message = ''
+ try:
+ while nb_tries < 5 and response is None:
+ try:
+ req = requests.post(
+ api_url, json=shipment_request, timeout=TIMEOUT)
+ except ssl.SSLError as e:
+ error_message = e.reason
+ nb_tries += 1
+ continue
+ req.raise_for_status()
+ response = req.json()
+ except requests.HTTPError as e:
+ error_message = e.args[0]
+
+ if error_message:
+ raise UPSError(
+ gettext('stock_package_shipping_ups.msg_ups_webservice_error',
+ message=error_message))
+
+ if 'Fault' in response:
+ error = response['Fault']['detail']['Errors']
+ message = '%s\n\n%s - %s' % (response['Fault']['faultstring'],
+ error['ErrorDetail']['PrimaryErrorCode']['Code'],
+ error['ErrorDetail']['PrimaryErrorCode']['Description'])
+ raise UPSError(
+ gettext('stock_package_shipping_ups.msg_ups_webservice_error',
+ message=message))
+
+ shipment_response = response['ShipmentResponse']
+ response_status = shipment_response['Response']['ResponseStatus']
+ if response_status['Code'] != '1':
+ raise UPSError(
+ gettext('stock_package_shipping_ups.msg_ups_webservice_error',
+ message=response_status['Description']))
+
+ shipment_results = shipment_response['ShipmentResults']
+ shipment.reference = shipment_results['ShipmentIdentificationNumber']
+ ups_packages = shipment_results['PackageResults']
+ if len(packages) == 1:
+ # In case only one package is requested UPS returns a dictionnary
+ # instead of a list of one package
+ ups_packages = [ups_packages]
+
+ for tryton_pkg, ups_pkg in zip_longest(packages, ups_packages):
+ label = fields.Binary.cast(base64.b64decode(
+ ups_pkg['ShippingLabel']['GraphicImage']))
+ tryton_pkg.shipping_reference = ups_pkg['TrackingNumber']
+ tryton_pkg.shipping_label = label
+ tryton_pkg.shipping_label_mimetype = (
+ carrier.shipping_label_mimetype)
+ Package.save(packages)
+ shipment.save()
+
+ return 'end'
+
+ def get_credential_pattern(self, shipment):
+ return {
+ 'company': shipment.company.id,
+ }
+
+ def get_credential(self, shipment):
+ pool = Pool()
+ UPSCredential = pool.get('carrier.credential.ups')
+
+ credential_pattern = self.get_credential_pattern(shipment)
+ for credential in UPSCredential.search([]):
+ if credential.match(credential_pattern):
+ return credential
+
+ def get_security(self, credential):
+ return {
+ 'UsernameToken': {
+ 'Username': credential.user_id,
+ 'Password': credential.password,
+ },
+ 'ServiceAccessToken': {
+ 'AccessLicenseNumber': credential.license,
+ },
+ }
+
+ def get_request_container(self, shipment):
+ return {
+ 'RequestOption': 'validate',
+ 'TransactionReference': {
+ 'CustomerContext': (shipment.number or '')[:512],
+ },
+ }
+
+ def get_shipping_party(self, party, address, usage=None):
+ shipping_party = {
+ 'Name': address.party_full_name[:35],
+ 'AttentionName': party.full_name[:35],
+ 'Address': {
+ 'AddressLine': [l[:35]
+ for l in (address.street or '').splitlines()[:3]],
+ 'City': address.city[:30],
+ 'PostalCode': (address.postal_code or '').replace(' ', '')[:9],
+ 'CountryCode': address.country.code if address.country else '',
+ },
+ }
+ phone = address.contact_mechanism_get({'phone', 'mobile'}, usage=usage)
+ if phone:
+ shipping_party['Phone'] = {
+ 'Number': re.sub('[() .-]', '', phone.value)[:15]
+ }
+ email = address.contact_mechanism_get('email')
+ if email and len(email.value) <= 50:
+ shipping_party['EMailAddress'] = email.value
+
+ return shipping_party
+
+ def get_payment_information(self, shipment, credential):
+ return {
+ 'ShipmentCharge': {
+ # Type 01 is for Transportation Charges
+ 'Type': '01',
+ 'BillShipper': {
+ 'AccountNumber': credential.account_number,
+ },
+ },
+ }
+
+ def get_package(self, use_metric, package):
+ pool = Pool()
+ UoM = pool.get('product.uom')
+ ModelData = pool.get('ir.model.data')
+
+ cm = UoM(ModelData.get_id('product', 'uom_centimeter'))
+ inch = UoM(ModelData.get_id('product', 'uom_inch'))
+
+ kg = UoM(ModelData.get_id('product', 'uom_kilogram'))
+ lb = UoM(ModelData.get_id('product', 'uom_pound'))
+
+ pkg = {
+ 'Packaging': {
+ 'Code': package.type.ups_code,
+ },
+ }
+ if (package.length is not None
+ and package.width is not None
+ and package.height is not None):
+ pkg['Dimensions'] = {
+ 'UnitOfMeasurement': {
+ 'Code': 'CM' if use_metric else 'IN',
+ },
+ 'Length': '%i' % round(UoM.compute_qty(package.length_uom,
+ package.length, cm if use_metric else inch)),
+ 'Width': '%i' % round(UoM.compute_qty(package.width_uom,
+ package.width, cm if use_metric else inch)),
+ 'Height': '%i' % round(UoM.compute_qty(package.height_uom,
+ package.height, cm if use_metric else inch)),
+ }
+ if package.total_weight is not None:
+ pkg['PackageWeight'] = {
+ 'UnitOfMeasurement': {
+ 'Code': 'KGS' if use_metric else 'LBS',
+ },
+ 'Weight': str(UoM.compute_qty(kg, package.total_weight,
+ kg if use_metric else lb)),
+ }
+ return pkg
+
+ def get_service_options(self, shipment):
+ service_options = {}
+ notifications = list(self.get_notifications(shipment))
+ if notifications:
+ service_options['Notification'] = notifications
+ return service_options
+
+ def get_notifications(self, shipment):
+ if not shipment.carrier.ups_notifications:
+ return
+ for code in shipment.carrier.ups_notifications:
+ shipping_to_address = shipment.shipping_to_address
+ email = shipping_to_address.contact_mechanism_get('email')
+ if email and len(email.value) <= 50:
+ notification = {
+ 'NotificationCode': code,
+ 'EMail': {
+ 'EMailAddress': email.value,
+ },
+ }
+ if code in {'012', '013'}:
+ phone = shipping_to_address.contact_mechanism_get(
+ {'phone', 'mobile'})
+ if phone and len(phone.value) <= 15:
+ notification['VoiceMessage'] = {
+ 'PhoneNumber': phone.value,
+ }
+ mobile = shipping_to_address.contact_mechanism_get(
+ 'mobile')
+ if mobile and len(mobile.value) <= 15:
+ notification['TextMessage'] = {
+ 'PhoneNumber': phone.value,
+ }
+ yield notification
+
+ def get_request(self, shipment, packages, credential):
+ shipper = self.get_shipping_party(
+ shipment.company.party, shipment.shipping_warehouse.address)
+ shipper['ShipperNumber'] = credential.account_number
+ # email is not required but must be associated with the UserId
+ # which can not be ensured.
+ shipper.pop('EMailAddress', None)
+
+ packages = [self.get_package(credential.use_metric, p)
+ for p in packages]
+ options = self.get_service_options(shipment)
+ if options:
+ for pkg in packages:
+ pkg['ShipmentServiceOptions'] = options
+ return {
+ 'UPSSecurity': self.get_security(credential),
+ 'ShipmentRequest': {
+ 'Request': self.get_request_container(shipment),
+ 'Shipment': {
+ 'Description': (shipment.shipping_description or '')[:50],
+ 'Shipper': shipper,
+ 'ShipTo': self.get_shipping_party(
+ shipment.shipping_to, shipment.shipping_to_address),
+ 'PaymentInformation': self.get_payment_information(
+ shipment, credential),
+ 'Service': {
+ 'Code': shipment.carrier.ups_service_type,
+ },
+ 'Package': packages,
+ },
+ 'LabelSpecification': {
+ 'LabelImageFormat': {
+ 'Code': shipment.carrier.ups_label_image_format,
+ },
+ 'LabelStockSize': {
+ 'Width': '4',
+ 'Height': shipment.carrier.ups_label_height,
+ },
+ }
+ },
+ }
diff --git a/modules/stock_package_shipping_ups/stock.xml b/modules/stock_package_shipping_ups/stock.xml
new file mode 100644
index 0000000000..328051d352
--- /dev/null
+++ b/modules/stock_package_shipping_ups/stock.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+ stock.package.type
+
+ package_type_form
+
+
+
+ Create UPS Shipping for Packages
+ stock.shipment.create_shipping.ups
+
+
+
diff --git a/modules/stock_package_shipping_ups/tests/__init__.py b/modules/stock_package_shipping_ups/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_package_shipping_ups/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_package_shipping_ups/tests/scenario_shipping_ups.rst b/modules/stock_package_shipping_ups/tests/scenario_shipping_ups.rst
new file mode 100644
index 0000000000..55bbd16472
--- /dev/null
+++ b/modules/stock_package_shipping_ups/tests/scenario_shipping_ups.rst
@@ -0,0 +1,244 @@
+========================================
+Stock Package Shipping with UPS scenario
+========================================
+
+Imports::
+
+ >>> import datetime
+ >>> import os
+ >>> from dateutil.relativedelta import relativedelta
+ >>> from decimal import Decimal
+ >>> from operator import attrgetter
+ >>> from proteus import Model, Wizard, Report
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> from trytond.modules.account.tests.tools import create_fiscalyear, \
+ ... create_chart, get_accounts, create_tax
+ >>> from trytond.modules.account_invoice.tests.tools import \
+ ... set_fiscalyear_invoice_sequences, create_payment_term
+ >>> today = datetime.date.today()
+
+Activate modules::
+
+ >>> config = activate_modules(
+ ... ['stock_package_shipping_ups', 'sale', 'sale_shipment_cost'])
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create fiscal year::
+
+ >>> fiscalyear = set_fiscalyear_invoice_sequences(
+ ... create_fiscalyear(company))
+ >>> fiscalyear.click('create_period')
+
+Create chart of accounts::
+
+ >>> _ = create_chart(company)
+ >>> accounts = get_accounts(company)
+ >>> revenue = accounts['revenue']
+ >>> expense = accounts['expense']
+
+Create a payment term::
+
+ >>> payment_term = create_payment_term()
+ >>> payment_term.save()
+
+Create parties::
+
+ >>> Party = Model.get('party.party')
+ >>> Country = Model.get('country.country')
+
+ >>> belgium = Country(code='BE', name='Belgium')
+ >>> belgium.save()
+ >>> france = Country(code='FR', name='France')
+ >>> france.save()
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+ >>> customer_address = customer.addresses.new()
+ >>> customer_address.street = 'Champs élysées'
+ >>> customer_address.postal_code = '75008'
+ >>> customer_address.city = 'Paris'
+ >>> customer_address.country = france
+ >>> customer_address.save()
+ >>> customer_phone = customer.contact_mechanisms.new()
+ >>> customer_phone.type = 'phone'
+ >>> customer_phone.value = '+33 93 842 8862'
+ >>> customer_phone.save()
+ >>> customer_email = customer.contact_mechanisms.new()
+ >>> customer_email.type = 'email'
+ >>> customer_email.value = 'customer@example.com'
+ >>> customer_email.save()
+
+Set the warehouse address::
+
+ >>> Address = Model.get('party.address')
+ >>> Location = Model.get('stock.location')
+ >>> warehouse, = Location.find([('type', '=', 'warehouse')])
+ >>> company_address = Address()
+ >>> company_address.party = company.party
+ >>> company_address.street = '2 rue de la Centrale'
+ >>> company_address.postal_code = '4000'
+ >>> company_address.city = 'Sclessin'
+ >>> company_address.country = belgium
+ >>> company_address.save()
+ >>> company_phone = company.party.contact_mechanisms.new()
+ >>> company_phone.type = 'phone'
+ >>> company_phone.value = '+32 4 2522122'
+ >>> company_phone.save()
+ >>> warehouse.address = company_address
+ >>> warehouse.save()
+
+Get some units::
+
+ >>> UoM = Model.get('product.uom')
+ >>> cm, = UoM.find([('symbol', '=', 'cm')])
+ >>> g, = UoM.find([('symbol', '=', 'g')])
+
+Create account category::
+
+ >>> ProductCategory = Model.get('product.category')
+ >>> account_category = ProductCategory(name="Account Category")
+ >>> account_category.accounting = True
+ >>> account_category.account_expense = expense
+ >>> account_category.account_revenue = revenue
+ >>> account_category.save()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+ >>> ProductTemplate = Model.get('product.template')
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.salable = True
+ >>> template.weight = 100
+ >>> template.weight_uom = g
+ >>> template.list_price = Decimal('10')
+ >>> template.account_category = account_category
+ >>> template.save()
+ >>> product, = template.products
+
+Create an Inventory::
+
+ >>> Inventory = Model.get('stock.inventory')
+ >>> storage, = Location.find([
+ ... ('code', '=', 'STO'),
+ ... ])
+ >>> inventory = Inventory()
+ >>> inventory.location = storage
+ >>> inventory_line = inventory.lines.new(product=product)
+ >>> inventory_line.quantity = 100.0
+ >>> inventory_line.expected_quantity = 0.0
+ >>> inventory.click('confirm')
+ >>> inventory.state
+ 'done'
+
+Create Package Type::
+
+ >>> PackageType = Model.get('stock.package.type')
+ >>> ups_box = PackageType(
+ ... name='UPS Box', ups_code='02',
+ ... length=10, length_uom=cm,
+ ... height=8, height_uom=cm,
+ ... width=1, width_uom=cm)
+ >>> ups_box.save()
+
+Create a UPS Carrier and the related credential::
+
+ >>> Carrier = Model.get('carrier')
+ >>> CarrierSelection = Model.get('carrier.selection')
+ >>> UPSCredential = Model.get('carrier.credential.ups')
+
+ >>> credential = UPSCredential()
+ >>> credential.company = company
+ >>> credential.user_id = os.getenv('UPS_USER_ID')
+ >>> credential.password = os.getenv('UPS_PASSWORD')
+ >>> credential.license = os.getenv('UPS_LICENSE')
+ >>> credential.account_number = os.getenv('UPS_ACCOUNT_NUMBER')
+ >>> credential.server = 'testing'
+ >>> credential.save()
+
+ >>> carrier_product_template = ProductTemplate()
+ >>> carrier_product_template.name = 'UPS Ground'
+ >>> carrier_product_template.default_uom = unit
+ >>> carrier_product_template.type = 'service'
+ >>> carrier_product_template.salable = True
+ >>> carrier_product_template.list_price = Decimal(20)
+ >>> carrier_product_template.account_category = account_category
+ >>> carrier_product_template.save()
+ >>> carrier_product, = carrier_product_template.products
+
+ >>> ups = Party(name='UPS')
+ >>> ups.save()
+
+ >>> carrier = Carrier()
+ >>> carrier.party = ups
+ >>> carrier.carrier_product = carrier_product
+ >>> carrier.shipping_service = 'ups'
+ >>> carrier.ups_service_type = '65'
+ >>> carrier.ups_label_image_format = 'GIF'
+ >>> carrier.ups_notifications = ['5', '7', '012']
+ >>> carrier.save()
+
+ >>> catchall_selection = CarrierSelection(carrier=carrier)
+ >>> catchall_selection.save()
+
+Create a sale and thus a shipment::
+
+ >>> Sale = Model.get('sale.sale')
+ >>> SaleLine = Model.get('sale.line')
+ >>> sale = Sale()
+ >>> sale.party = customer
+ >>> sale.shipment_address = customer_address
+ >>> sale.payment_term = payment_term
+ >>> sale.invoice_method = 'order'
+ >>> sale.carrier = carrier
+ >>> sale_line = sale.lines.new()
+ >>> sale_line.product = product
+ >>> sale_line.quantity = 2.0
+ >>> sale.click('quote')
+ >>> sale.click('confirm')
+ >>> sale.click('process')
+
+Create the packs and ship the shipment::
+
+ >>> Package = Model.get('stock.package')
+ >>> shipment, = sale.shipments
+ >>> shipment.shipping_description = 'Football Players'
+ >>> shipment.click('assign_try')
+ True
+ >>> shipment.click('pick')
+ >>> pack = shipment.packages.new()
+ >>> pack.type = ups_box
+ >>> pack_move, = pack.moves.find([])
+ >>> pack.moves.append(pack_move)
+ >>> shipment.click('pack')
+
+ >>> create_shipping = Wizard('stock.shipment.create_shipping', [shipment])
+ >>> shipment.reload()
+ >>> shipment.reference != ''
+ True
+ >>> pack, = shipment.root_packages
+ >>> pack.shipping_label is not None
+ True
+ >>> pack.shipping_label_mimetype
+ 'image/gif'
+ >>> pack.shipping_reference is not None
+ True
+ >>> pack.shipping_tracking_url.startswith('https://www.ups.com/track?')
+ True
+ >>> pack.shipping_reference in pack.shipping_tracking_url
+ True
+
+Because there is only one box, the pack shipping number is also the shipment
+identification number::
+
+ >>> pack.shipping_reference == shipment.reference
+ True
diff --git a/modules/stock_package_shipping_ups/tests/test_module.py b/modules/stock_package_shipping_ups/tests/test_module.py
new file mode 100644
index 0000000000..d188e0e2ae
--- /dev/null
+++ b/modules/stock_package_shipping_ups/tests/test_module.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class ShippingUpsTestCase(ModuleTestCase):
+ 'Test Shipping Ups module'
+ module = 'stock_package_shipping_ups'
+
+
+del ModuleTestCase
diff --git a/modules/stock_package_shipping_ups/tests/test_scenario.py b/modules/stock_package_shipping_ups/tests/test_scenario.py
new file mode 100644
index 0000000000..23f5380d62
--- /dev/null
+++ b/modules/stock_package_shipping_ups/tests/test_scenario.py
@@ -0,0 +1,13 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import os
+
+from trytond.tests.test_tryton import load_doc_tests
+
+if (os.getenv('UPS_USER_ID')
+ and os.getenv('UPS_PASSWORD')
+ and os.getenv('UPS_LICENSE')
+ and os.getenv('UPS_ACCOUNT_NUMBER')):
+ def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_package_shipping_ups/tox.ini b/modules/stock_package_shipping_ups/tox.ini
new file mode 100644
index 0000000000..6e2d007fe7
--- /dev/null
+++ b/modules/stock_package_shipping_ups/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_package_shipping_ups/* -m unittest discover -s tests
+ coverage report --include=./**/stock_package_shipping_ups/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_package_shipping_ups/tryton.cfg b/modules/stock_package_shipping_ups/tryton.cfg
new file mode 100644
index 0000000000..d7bf505f7d
--- /dev/null
+++ b/modules/stock_package_shipping_ups/tryton.cfg
@@ -0,0 +1,15 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ res
+ party
+ product
+ stock
+ stock_shipment_measurements
+ stock_package
+ stock_package_shipping
+xml:
+ carrier.xml
+ stock.xml
+ message.xml
diff --git a/modules/stock_package_shipping_ups/view/carrier_form.xml b/modules/stock_package_shipping_ups/view/carrier_form.xml
new file mode 100644
index 0000000000..c06f7e7255
--- /dev/null
+++ b/modules/stock_package_shipping_ups/view/carrier_form.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping_ups/view/package_type_form.xml b/modules/stock_package_shipping_ups/view/package_type_form.xml
new file mode 100644
index 0000000000..dfd359a44e
--- /dev/null
+++ b/modules/stock_package_shipping_ups/view/package_type_form.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_package_shipping_ups/view/ups_credential_form.xml b/modules/stock_package_shipping_ups/view/ups_credential_form.xml
new file mode 100644
index 0000000000..7a400076ef
--- /dev/null
+++ b/modules/stock_package_shipping_ups/view/ups_credential_form.xml
@@ -0,0 +1,21 @@
+
+
+
diff --git a/modules/stock_package_shipping_ups/view/ups_credential_list.xml b/modules/stock_package_shipping_ups/view/ups_credential_list.xml
new file mode 100644
index 0000000000..3ea329081b
--- /dev/null
+++ b/modules/stock_package_shipping_ups/view/ups_credential_list.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/stock_product_location/.drone.yml b/modules/stock_product_location/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_product_location/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_product_location/.flake8 b/modules/stock_product_location/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_product_location/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_product_location/.isort.cfg b/modules/stock_product_location/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_product_location/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_product_location/CHANGELOG b/modules/stock_product_location/CHANGELOG
new file mode 100644
index 0000000000..db13e6eb72
--- /dev/null
+++ b/modules/stock_product_location/CHANGELOG
@@ -0,0 +1,92 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+* Add default locations on templates
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+* Use MatchMixin for ProductLocation
+
+Version 4.2.0 - 2016-11-28
+* Bug fixes (see mercurial logs for details)
+* Use product default location for production outputs
+
+Version 4.0.0 - 2016-05-02
+* Bug fixes (see mercurial logs for details)
+* Add Python3 support
+
+Version 3.8.0 - 2015-11-02
+* Bug fixes (see mercurial logs for details)
+
+Version 3.6.0 - 2015-04-20
+* Bug fixes (see mercurial logs for details)
+* Add support for PyPy
+Version 3.4.0 - 2014-10-20
+* Bug fixes (see mercurial logs for details)
+
+Version 3.2.0 - 2014-04-21
+* Bug fixes (see mercurial logs for details)
+
+Version 3.0.0 - 2013-10-21
+* Bug fixes (see mercurial logs for details)
+
+Version 2.8.0 - 2013-04-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.6.0 - 2012-10-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.4.0 - 2012-04-24
+* Bug fixes (see mercurial logs for details)
+
+Version 2.2.0 - 2011-10-25
+* Bug fixes (see mercurial logs for details)
+
+Version 2.0.0 - 2011-04-27
+* Bug fixes (see mercurial logs for details)
+
+Version 1.8.0 - 2010-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 1.6.0 - 2010-05-12
+* Bug fixes (see mercurial logs for details)
+
+Version 1.4.0 - 2009-10-19
+* Bug fixes (see mercurial logs for details)
+
+Version 1.2.0 - 2009-07-31
+* Initial release
diff --git a/modules/stock_product_location/COPYRIGHT b/modules/stock_product_location/COPYRIGHT
new file mode 100644
index 0000000000..068e2b6331
--- /dev/null
+++ b/modules/stock_product_location/COPYRIGHT
@@ -0,0 +1,16 @@
+Copyright (C) 2008-2022 Cédric Krier.
+Copyright (C) 2008-2012 Bertrand Chenal.
+Copyright (C) 2008-2022 B2CK SPRL.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_product_location/LICENSE b/modules/stock_product_location/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_product_location/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_product_location/MANIFEST.in b/modules/stock_product_location/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_product_location/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_product_location/README.rst b/modules/stock_product_location/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_product_location/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_product_location/__init__.py b/modules/stock_product_location/__init__.py
new file mode 100644
index 0000000000..79c40e36d9
--- /dev/null
+++ b/modules/stock_product_location/__init__.py
@@ -0,0 +1,21 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import location, product, production
+
+
+def register():
+ Pool.register(
+ product.Template,
+ product.Product,
+ location.ProductLocation,
+ location.Move,
+ location.ShipmentIn,
+ location.ShipmentOutReturn,
+ module='stock_product_location', type_='model')
+ Pool.register(
+ production.Production,
+ module='stock_product_location', type_='model',
+ depends=['production'])
diff --git a/modules/stock_product_location/doc/index.rst b/modules/stock_product_location/doc/index.rst
new file mode 100644
index 0000000000..01e8917662
--- /dev/null
+++ b/modules/stock_product_location/doc/index.rst
@@ -0,0 +1,8 @@
+Stock Product Location Module
+#############################
+
+The Stock Product Location Module adds on the product form a list of
+preferred location by warehouse. This list is used when a supplier
+shipment is received: the auto-generated Inventory Moves will use as
+default destination the preferred locations associated to the current
+warehouse.
diff --git a/modules/stock_product_location/locale/bg.po b/modules/stock_product_location/locale/bg.po
new file mode 100644
index 0000000000..5ae32bb2b5
--- /dev/null
+++ b/modules/stock_product_location/locale/bg.po
@@ -0,0 +1,33 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr "Местонахождения по подразбиране"
+
+#, fuzzy
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Местонахождения по подразбиране"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Местонахождение на съхранение"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Продукт"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Склад"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "Местонахождение на продукт"
diff --git a/modules/stock_product_location/locale/ca.po b/modules/stock_product_location/locale/ca.po
new file mode 100644
index 0000000000..2566796c59
--- /dev/null
+++ b/modules/stock_product_location/locale/ca.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr "Ubicacions predeterminades"
+
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Ubicacions per defecte"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Ubicació d'emmagatzematge"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr "Variant"
+
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Producte"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Magatzem"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "Ubicació de producte"
diff --git a/modules/stock_product_location/locale/cs.po b/modules/stock_product_location/locale/cs.po
new file mode 100644
index 0000000000..27c23b4c5f
--- /dev/null
+++ b/modules/stock_product_location/locale/cs.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr ""
+
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr ""
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr ""
diff --git a/modules/stock_product_location/locale/de.po b/modules/stock_product_location/locale/de.po
new file mode 100644
index 0000000000..06c6a43d21
--- /dev/null
+++ b/modules/stock_product_location/locale/de.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr "Standardlagerorte"
+
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Standardlagerorte"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Lagerort"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr "Variante"
+
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Artikel"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Logistikstandort"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "Artikel Lagerort"
diff --git a/modules/stock_product_location/locale/es.po b/modules/stock_product_location/locale/es.po
new file mode 100644
index 0000000000..cad48afe1f
--- /dev/null
+++ b/modules/stock_product_location/locale/es.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr "Ubicaciones por defecto"
+
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Ubicaciones por defecto"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Ubicación interna"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr "Variante"
+
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Producto"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Almacén"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "Ubicación de producto"
diff --git a/modules/stock_product_location/locale/es_419.po b/modules/stock_product_location/locale/es_419.po
new file mode 100644
index 0000000000..0144710c36
--- /dev/null
+++ b/modules/stock_product_location/locale/es_419.po
@@ -0,0 +1,32 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Ubicación de almacenamiento"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Ubicación de almacenamiento"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Bodega"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr ""
diff --git a/modules/stock_product_location/locale/et.po b/modules/stock_product_location/locale/et.po
new file mode 100644
index 0000000000..3b81a8a068
--- /dev/null
+++ b/modules/stock_product_location/locale/et.po
@@ -0,0 +1,33 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr "Vaikimisi asukoht"
+
+#, fuzzy
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Vaikimisi asukoht"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Ladustamise asukoht"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Toode"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Ladu"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "Toote asukoht"
diff --git a/modules/stock_product_location/locale/fa.po b/modules/stock_product_location/locale/fa.po
new file mode 100644
index 0000000000..275008bd40
--- /dev/null
+++ b/modules/stock_product_location/locale/fa.po
@@ -0,0 +1,33 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr "مکان های پیشفرض"
+
+#, fuzzy
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "مکان های پیشفرض"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "محل انبار"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "محصول"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "انبار"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "مکان محصول"
diff --git a/modules/stock_product_location/locale/fi.po b/modules/stock_product_location/locale/fi.po
new file mode 100644
index 0000000000..27c23b4c5f
--- /dev/null
+++ b/modules/stock_product_location/locale/fi.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr ""
+
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr ""
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr ""
diff --git a/modules/stock_product_location/locale/fr.po b/modules/stock_product_location/locale/fr.po
new file mode 100644
index 0000000000..b0ba45ae3c
--- /dev/null
+++ b/modules/stock_product_location/locale/fr.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr "Emplacements par défaut"
+
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Emplacements par défaut"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Emplacement de stockage"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr "Variante"
+
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Produit"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Entrepôt"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "Emplacement produit"
diff --git a/modules/stock_product_location/locale/hu.po b/modules/stock_product_location/locale/hu.po
new file mode 100644
index 0000000000..435c130fec
--- /dev/null
+++ b/modules/stock_product_location/locale/hu.po
@@ -0,0 +1,33 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr "Alapértelmezett raktár hely"
+
+#, fuzzy
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Alapértelmezett raktár hely"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Raktár helye"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Termék"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Raktár"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "Termék raktárhelye"
diff --git a/modules/stock_product_location/locale/id.po b/modules/stock_product_location/locale/id.po
new file mode 100644
index 0000000000..e75bb2a4f6
--- /dev/null
+++ b/modules/stock_product_location/locale/id.po
@@ -0,0 +1,32 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Lokasi Penyimpanan"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Lokasi Penyimpanan"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Produk"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Gudang"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr ""
diff --git a/modules/stock_product_location/locale/it.po b/modules/stock_product_location/locale/it.po
new file mode 100644
index 0000000000..adf7d1831f
--- /dev/null
+++ b/modules/stock_product_location/locale/it.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr "Luoghi predefiniti"
+
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Luoghi predefiniti"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Luogo immagazzinamento"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr "Variante"
+
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Prodotto"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Magazzino"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "Posizione del prodotto"
diff --git a/modules/stock_product_location/locale/lo.po b/modules/stock_product_location/locale/lo.po
new file mode 100644
index 0000000000..a10936bbf2
--- /dev/null
+++ b/modules/stock_product_location/locale/lo.po
@@ -0,0 +1,33 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr "ບ່ອນເກັບມ້ຽນເດີມ"
+
+#, fuzzy
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "ບ່ອນເກັບມ້ຽນເດີມ"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "ບ່ອນເກັບມ້ຽນ"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "ຜະລິດຕະພັນ"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "ສາງໃຫຍ່"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "ບ່ອນເກັບມ້ຽນຜະລິດຕະພັນ"
diff --git a/modules/stock_product_location/locale/lt.po b/modules/stock_product_location/locale/lt.po
new file mode 100644
index 0000000000..27c23b4c5f
--- /dev/null
+++ b/modules/stock_product_location/locale/lt.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr ""
+
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr ""
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr ""
diff --git a/modules/stock_product_location/locale/nl.po b/modules/stock_product_location/locale/nl.po
new file mode 100644
index 0000000000..1c541afd09
--- /dev/null
+++ b/modules/stock_product_location/locale/nl.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr "Standaard locaties"
+
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Standaard locaties"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Opslaglocatie"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr "Variant"
+
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Product"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Magazijn"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "Productlocatie"
diff --git a/modules/stock_product_location/locale/pl.po b/modules/stock_product_location/locale/pl.po
new file mode 100644
index 0000000000..3f4336b69e
--- /dev/null
+++ b/modules/stock_product_location/locale/pl.po
@@ -0,0 +1,33 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr "Domyślne lokalizacje"
+
+#, fuzzy
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Domyślne lokalizacje"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Produkt"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Magazyn"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "Lokalizacja produktu"
diff --git a/modules/stock_product_location/locale/pt.po b/modules/stock_product_location/locale/pt.po
new file mode 100644
index 0000000000..e81b82fb25
--- /dev/null
+++ b/modules/stock_product_location/locale/pt.po
@@ -0,0 +1,33 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr "Localizações padrão"
+
+#, fuzzy
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Localizações padrão"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Localização de armazenamento"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Produto"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Almoxarifado"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "Localização do produto"
diff --git a/modules/stock_product_location/locale/ro.po b/modules/stock_product_location/locale/ro.po
new file mode 100644
index 0000000000..a3114d9952
--- /dev/null
+++ b/modules/stock_product_location/locale/ro.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr "Locații Implicite"
+
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Locații Implicite"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Locație de Depozitare"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr "Varianta"
+
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Produs"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Depozit"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "Locația Produs"
diff --git a/modules/stock_product_location/locale/ru.po b/modules/stock_product_location/locale/ru.po
new file mode 100644
index 0000000000..7a9ed05a5a
--- /dev/null
+++ b/modules/stock_product_location/locale/ru.po
@@ -0,0 +1,35 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Хранение Местоположение"
+
+#, fuzzy
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Хранение Местоположение"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Товарно материальные ценности (ТМЦ)"
+
+#, fuzzy
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Товарный склад"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr ""
diff --git a/modules/stock_product_location/locale/sl.po b/modules/stock_product_location/locale/sl.po
new file mode 100644
index 0000000000..c5962af3bc
--- /dev/null
+++ b/modules/stock_product_location/locale/sl.po
@@ -0,0 +1,33 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr "Privzete lokacije"
+
+#, fuzzy
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Privzete lokacije"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Shramba"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Izdelek"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Skladišče"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "Lokacija izdelkov"
diff --git a/modules/stock_product_location/locale/tr.po b/modules/stock_product_location/locale/tr.po
new file mode 100644
index 0000000000..3533be2563
--- /dev/null
+++ b/modules/stock_product_location/locale/tr.po
@@ -0,0 +1,33 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr "Ürün Konumu"
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr "Depolama Konumu"
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr "Ürün"
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr "Depo"
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr "Ürün Konumu"
diff --git a/modules/stock_product_location/locale/uk.po b/modules/stock_product_location/locale/uk.po
new file mode 100644
index 0000000000..27c23b4c5f
--- /dev/null
+++ b/modules/stock_product_location/locale/uk.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr ""
+
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr ""
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr ""
diff --git a/modules/stock_product_location/locale/zh_CN.po b/modules/stock_product_location/locale/zh_CN.po
new file mode 100644
index 0000000000..27c23b4c5f
--- /dev/null
+++ b/modules/stock_product_location/locale/zh_CN.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,locations:"
+msgid "Default Locations"
+msgstr ""
+
+msgctxt "field:product.template,locations:"
+msgid "Default Locations"
+msgstr ""
+
+msgctxt "field:stock.product.location,location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.product.location,product:"
+msgid "Variant"
+msgstr ""
+
+msgctxt "field:stock.product.location,template:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.product.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "model:stock.product.location,name:"
+msgid "Product Location"
+msgstr ""
diff --git a/modules/stock_product_location/location.py b/modules/stock_product_location/location.py
new file mode 100644
index 0000000000..b18d79a868
--- /dev/null
+++ b/modules/stock_product_location/location.py
@@ -0,0 +1,91 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.model import (
+ MatchMixin, ModelSQL, ModelView, fields, sequence_ordered)
+from trytond.pool import PoolMeta
+from trytond.pyson import Bool, Eval, If
+
+
+class ProductLocation(sequence_ordered(), ModelSQL, ModelView, MatchMixin):
+ '''
+ Product Location
+ It defines the default storage location by warehouse for a product.
+ '''
+ __name__ = 'stock.product.location'
+ template = fields.Many2One(
+ 'product.template', "Product",
+ required=True, ondelete='CASCADE',
+ domain=[
+ If(Bool(Eval('product')),
+ ('products', '=', Eval('product')),
+ ()),
+ ])
+ product = fields.Many2One(
+ 'product.product', "Variant", ondelete='CASCADE',
+ domain=[
+ If(Bool(Eval('template')),
+ ('template', '=', Eval('template')),
+ ()),
+ ])
+ warehouse = fields.Many2One('stock.location', 'Warehouse', required=True,
+ domain=[('type', '=', 'warehouse')], ondelete='CASCADE')
+ location = fields.Many2One('stock.location', 'Storage Location',
+ required=True, ondelete='CASCADE',
+ domain=[
+ ('type', '=', 'storage'),
+ ('parent', 'child_of', If(Bool(Eval('warehouse')),
+ [Eval('warehouse')], [])),
+ ])
+
+ @classmethod
+ def __register__(cls, module_name):
+ table = cls.__table_handler__(module_name)
+
+ super().__register__(module_name)
+
+ # Migration from 5.6: Add template on locations
+ table.not_null_action('product', 'remove')
+
+ @fields.depends('product', '_parent_product.template')
+ def on_change_product(self):
+ if self.product:
+ self.template = self.product.template
+
+
+class Move(metaclass=PoolMeta):
+ __name__ = 'stock.move'
+
+ def set_product_location(self, field='to_location', **pattern):
+ assert field in {'from_location', 'to_location'}
+ if getattr(self, 'shipment', None):
+ pattern.setdefault('warehouse', self.shipment.warehouse.id)
+
+ if self.product:
+ pattern.setdefault('template', self.product.template.id)
+ pattern.setdefault('product', self.product.id)
+
+ locations = self.product.locations + self.product.template.locations
+ for product_location in locations:
+ if product_location.match(pattern):
+ setattr(self, field, product_location.location)
+ break
+
+
+class ShipmentIn(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in'
+
+ def _get_inventory_move(self, incoming_move):
+ move = super()._get_inventory_move(incoming_move)
+ if move:
+ move.set_product_location(warehouse=self.warehouse.id)
+ return move
+
+
+class ShipmentOutReturn(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out.return'
+
+ def _get_inventory_move(self, incoming_move):
+ move = super()._get_inventory_move(incoming_move)
+ if move:
+ move.set_product_location(warehouse=self.warehouse.id)
+ return move
diff --git a/modules/stock_product_location/location.xml b/modules/stock_product_location/location.xml
new file mode 100644
index 0000000000..a259918194
--- /dev/null
+++ b/modules/stock_product_location/location.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+ stock.product.location
+ form
+ product_location_form
+
+
+ stock.product.location
+ tree
+ product_location_tree
+
+
+
diff --git a/modules/stock_product_location/product.py b/modules/stock_product_location/product.py
new file mode 100644
index 0000000000..28120a649d
--- /dev/null
+++ b/modules/stock_product_location/product.py
@@ -0,0 +1,79 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.model import fields
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Eval
+
+
+class Template(metaclass=PoolMeta):
+ __name__ = 'product.template'
+ locations = fields.One2Many('stock.product.location', 'template',
+ "Default Locations",
+ states={
+ 'invisible': ~Eval('type').in_(['goods', 'assets']),
+ })
+
+ @classmethod
+ def copy(cls, templates, default=None):
+ pool = Pool()
+ ProductLocation = pool.get('stock.product.location')
+ if default is None:
+ default = {}
+ else:
+ default = default.copy()
+
+ copy_locations = 'locations' not in default
+ default.setdefault('locations', None)
+ new_templates = super().copy(templates, default)
+ if copy_locations:
+ old2new = {}
+ to_copy = []
+ for template, new_template in zip(templates, new_templates):
+ to_copy.extend(l for l in template.locations if not l.product)
+ old2new[template.id] = new_template.id
+ if to_copy:
+ ProductLocation.copy(to_copy, {
+ 'template': lambda d: old2new[d['template']],
+ })
+ return new_templates
+
+
+class Product(metaclass=PoolMeta):
+ __name__ = 'product.product'
+ locations = fields.One2Many('stock.product.location', 'product',
+ "Default Locations",
+ domain=[
+ ('template', '=', Eval('template')),
+ ],
+ states={
+ 'invisible': ~Eval('type').in_(['goods', 'assets']),
+ })
+
+ @classmethod
+ def copy(cls, products, default=None):
+ pool = Pool()
+ ProductLocation = pool.get('stock.product.location')
+ if default is None:
+ default = {}
+ else:
+ default = default.copy()
+
+ copy_locations = 'locations' not in default
+ if 'template' in default:
+ default.setdefault('locations', None)
+ new_products = super().copy(products, default)
+ if 'template' in default and copy_locations:
+ template2new = {}
+ product2new = {}
+ to_copy = []
+ for product, new_product in zip(products, new_products):
+ if product.locations:
+ to_copy.extend(product.locations)
+ template2new[product.template.id] = new_product.template.id
+ product2new[product.id] = new_product.id
+ if to_copy:
+ ProductLocation.copy(to_copy, {
+ 'product': lambda d: product2new[d['product']],
+ 'template': lambda d: template2new[d['template']],
+ })
+ return new_products
diff --git a/modules/stock_product_location/product.xml b/modules/stock_product_location/product.xml
new file mode 100644
index 0000000000..f2cbe333ca
--- /dev/null
+++ b/modules/stock_product_location/product.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ product.template
+
+ product_form
+
+
+
diff --git a/modules/stock_product_location/production.py b/modules/stock_product_location/production.py
new file mode 100644
index 0000000000..b4bd9e159a
--- /dev/null
+++ b/modules/stock_product_location/production.py
@@ -0,0 +1,20 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.pool import Pool, PoolMeta
+
+
+class Production(metaclass=PoolMeta):
+ __name__ = 'production'
+
+ def _explode_move_values(
+ self, from_location, to_location, company, bom_io, quantity):
+ pool = Pool()
+ ProductionBomOutput = pool.get('production.bom.output')
+ move = super(Production, self)._explode_move_values(
+ from_location, to_location, company, bom_io, quantity)
+ if move and isinstance(bom_io, ProductionBomOutput):
+ for product_location in bom_io.product.locations:
+ if product_location.warehouse != to_location.warehouse:
+ continue
+ move.to_location = product_location.location
+ return move
diff --git a/modules/stock_product_location/setup.py b/modules/stock_product_location/setup.py
new file mode 100755
index 0000000000..844525d0d6
--- /dev/null
+++ b/modules/stock_product_location/setup.py
@@ -0,0 +1,153 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_product_location'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = ['python-sql >= 0.4']
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [get_require_version('proteus')]
+for dep in ['production']:
+ tests_require.append(get_require_version('trytond_%s' % dep))
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module to add default location on product',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_product_location',
+ },
+ keywords='tryton stock product location',
+ package_dir={'trytond.modules.stock_product_location': '.'},
+ packages=(
+ ['trytond.modules.stock_product_location']
+ + ['trytond.modules.stock_product_location.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_product_location': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', 'label.odt',
+ 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Legal Industry',
+ 'Intended Audience :: Manufacturing',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_product_location = trytond.modules.stock_product_location
+ """,
+ )
diff --git a/modules/stock_product_location/tests/__init__.py b/modules/stock_product_location/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_product_location/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_product_location/tests/scenario_product_copy_locations.rst b/modules/stock_product_location/tests/scenario_product_copy_locations.rst
new file mode 100644
index 0000000000..66a4e833a1
--- /dev/null
+++ b/modules/stock_product_location/tests/scenario_product_copy_locations.rst
@@ -0,0 +1,67 @@
+=============================
+Product Copy Locaton Scenario
+=============================
+
+Imports::
+
+ >>> from decimal import Decimal
+ >>> from proteus import Model
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+
+Activate modules::
+
+ >>> config = activate_modules('stock_product_location')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+
+Create new location::
+
+ >>> Location = Model.get('stock.location')
+ >>> child_loc = Location()
+ >>> child_loc.name = 'Child Location'
+ >>> child_loc.parent = storage_loc
+ >>> child_loc.code = 'CHI'
+ >>> child_loc.save()
+
+Create a product with suppliers::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template_location = template.locations.new()
+ >>> template_location.warehouse = warehouse_loc
+ >>> template_location.location = child_loc
+ >>> template.save()
+ >>> product, = template.products
+ >>> product_location = product.locations.new()
+ >>> product_location.warehouse = warehouse_loc
+ >>> product_location.location = child_loc
+ >>> product_location.template == template
+ True
+ >>> product.save()
+
+Location is copied when copying the template::
+
+ >>> template_copy, = template.duplicate()
+ >>> product_copy, = template_copy.products
+ >>> len(template_copy.locations)
+ 2
+ >>> len(product_copy.locations)
+ 1
diff --git a/modules/stock_product_location/tests/scenario_stock_product_location.rst b/modules/stock_product_location/tests/scenario_stock_product_location.rst
new file mode 100644
index 0000000000..b757d3f141
--- /dev/null
+++ b/modules/stock_product_location/tests/scenario_stock_product_location.rst
@@ -0,0 +1,126 @@
+================================
+Stock Product Locations Scenario
+================================
+
+Imports::
+
+ >>> import datetime
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> today = datetime.date.today()
+
+Activate modules::
+
+ >>> config = activate_modules('stock_product_location')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create customer::
+
+ >>> Party = Model.get('party.party')
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+
+Create supplier::
+
+ >>> supplier = Party(name='Suppier')
+ >>> supplier.save()
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+ >>> input_loc, = Location.find([('code', '=', 'IN')])
+
+Create new location::
+
+ >>> Location = Model.get('stock.location')
+ >>> child_loc = Location()
+ >>> child_loc.name = 'Child Location'
+ >>> child_loc.parent = storage_loc
+ >>> child_loc.code = 'CHI'
+ >>> child_loc.save()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template.save()
+ >>> product, = template.products
+ >>> product_location = product.locations.new()
+ >>> product_location.warehouse = warehouse_loc
+ >>> product_location.location = child_loc
+ >>> product.save()
+
+Create Shipment in::
+
+ >>> Shipmentin = Model.get('stock.shipment.in')
+ >>> shipment_in = Shipmentin()
+ >>> shipment_in.planned_date = today
+ >>> shipment_in.supplier = supplier
+ >>> shipment_in.warehouse = warehouse_loc
+ >>> shipment_in.company = company
+
+Add one shipment line of product::
+
+ >>> move = shipment_in.incoming_moves.new()
+ >>> move.product = product
+ >>> move.uom = unit
+ >>> move.quantity = 1
+ >>> move.from_location = supplier_loc
+ >>> move.to_location = input_loc
+ >>> move.company = company
+ >>> move.unit_price = Decimal('1')
+ >>> move.currency = company.currency
+ >>> shipment_in.save()
+
+Test that to_location is child location on reception::
+
+ >>> shipment_in.click('receive')
+ >>> move, = shipment_in.inventory_moves
+ >>> move.to_location == child_loc
+ True
+
+Create return shipment out::
+
+ >>> Shipment_out_Return = Model.get('stock.shipment.out.return')
+ >>> shipment_out_return = Shipment_out_Return()
+ >>> shipment_out_return.customer = customer
+ >>> shipment_out_return.save()
+
+Add one shipment return line::
+
+ >>> move = shipment_out_return.incoming_moves.new()
+ >>> move.product = product
+ >>> move.uom =unit
+ >>> move.quantity = 1
+ >>> move.from_location = customer_loc
+ >>> move.to_location = input_loc
+ >>> move.company = company
+ >>> move.unit_price = Decimal('1')
+ >>> move.currency = company.currency
+ >>> shipment_out_return.save()
+
+Test that to_location is child location on reception::
+
+ >>> shipment_out_return.click('receive')
+ >>> move, = shipment_out_return.inventory_moves
+ >>> move.to_location == child_loc
+ True
diff --git a/modules/stock_product_location/tests/scenario_stock_product_location_production.rst b/modules/stock_product_location/tests/scenario_stock_product_location_production.rst
new file mode 100644
index 0000000000..e3bae98fcb
--- /dev/null
+++ b/modules/stock_product_location/tests/scenario_stock_product_location_production.rst
@@ -0,0 +1,148 @@
+===========================================
+Stock Product Locations Production Scenario
+===========================================
+
+Imports::
+
+ >>> import datetime
+ >>> from decimal import Decimal
+ >>> from proteus import Model
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company
+
+Activate modules::
+
+ >>> _ = activate_modules(['stock_product_location', 'production'])
+
+Create company::
+
+ >>> _ = create_company()
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+ >>> production_loc, = Location.find([('code', '=', 'PROD')])
+
+Create new location::
+
+ >>> Location = Model.get('stock.location')
+ >>> child_loc = Location()
+ >>> child_loc.name = 'Child Location'
+ >>> child_loc.parent = storage_loc
+ >>> child_loc.code = 'CHI'
+ >>> child_loc.save()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+ >>> ProductTemplate = Model.get('product.template')
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.producible = True
+ >>> template.list_price = Decimal(30)
+ >>> template.save()
+ >>> product, = template.products
+ >>> product_location = product.locations.new()
+ >>> product_location.warehouse = warehouse_loc
+ >>> product_location.location = child_loc
+ >>> product.save()
+
+Create Components::
+
+ >>> template1 = ProductTemplate()
+ >>> template1.name = 'component 1'
+ >>> template1.default_uom = unit
+ >>> template1.type = 'goods'
+ >>> template1.list_price = Decimal(5)
+ >>> template1.save()
+ >>> component1, = template1.products
+
+ >>> meter, = ProductUom.find([('name', '=', 'Meter')])
+ >>> centimeter, = ProductUom.find([('name', '=', 'Centimeter')])
+ >>> template2 = ProductTemplate()
+ >>> template2.name = 'component 2'
+ >>> template2.default_uom = meter
+ >>> template2.type = 'goods'
+ >>> template2.list_price = Decimal(7)
+ >>> template2.save()
+ >>> component2, = template2.products
+
+Create Bill of Material::
+
+ >>> BOM = Model.get('production.bom')
+ >>> BOMInput = Model.get('production.bom.input')
+ >>> BOMOutput = Model.get('production.bom.output')
+ >>> bom = BOM(name='product')
+ >>> input1 = BOMInput()
+ >>> bom.inputs.append(input1)
+ >>> input1.product = component1
+ >>> input1.quantity = 5
+ >>> input2 = BOMInput()
+ >>> bom.inputs.append(input2)
+ >>> input2.product = component2
+ >>> input2.quantity = 150
+ >>> input2.uom = centimeter
+ >>> output = BOMOutput()
+ >>> bom.outputs.append(output)
+ >>> output.product = product
+ >>> output.quantity = 1
+ >>> bom.save()
+
+ >>> ProductBom = Model.get('product.product-production.bom')
+ >>> product.boms.append(ProductBom(bom=bom))
+ >>> product.save()
+
+Create an Inventory::
+
+ >>> Inventory = Model.get('stock.inventory')
+ >>> InventoryLine = Model.get('stock.inventory.line')
+ >>> inventory = Inventory()
+ >>> inventory.location = storage_loc
+ >>> inventory_line1 = InventoryLine()
+ >>> inventory.lines.append(inventory_line1)
+ >>> inventory_line1.product = component1
+ >>> inventory_line1.quantity = 20
+ >>> inventory_line2 = InventoryLine()
+ >>> inventory.lines.append(inventory_line2)
+ >>> inventory_line2.product = component2
+ >>> inventory_line2.quantity = 6
+ >>> inventory.click('confirm')
+ >>> inventory.state
+ 'done'
+
+Make a production::
+
+ >>> Production = Model.get('production')
+ >>> production = Production()
+ >>> production.planned_date = datetime.date.today()
+ >>> production.product = product
+ >>> production.bom = bom
+ >>> production.quantity = 2
+
+Test storage location of the warehouse::
+
+ >> warehouse_loc.storage_location == storage_loc
+ True
+
+Test locations of the production inputs::
+
+ >>> all([input_.from_location == storage_loc for \
+ ... input_ in production.inputs])
+ True
+ >>> all([input_.to_location == production_loc for \
+ ... input_ in production.inputs])
+ True
+
+Test location of the production output::
+
+ >>> output, = production.outputs
+ >>> output.from_location == production_loc
+ True
+ >>> output.to_location == child_loc
+ True
diff --git a/modules/stock_product_location/tests/scenario_stock_product_location_template.rst b/modules/stock_product_location/tests/scenario_stock_product_location_template.rst
new file mode 100644
index 0000000000..01feb08cd9
--- /dev/null
+++ b/modules/stock_product_location/tests/scenario_stock_product_location_template.rst
@@ -0,0 +1,125 @@
+=========================================
+Stock Product Locations Template Scenario
+=========================================
+
+Imports::
+
+ >>> import datetime
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> today = datetime.date.today()
+
+Activate modules::
+
+ >>> config = activate_modules('stock_product_location')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create customer::
+
+ >>> Party = Model.get('party.party')
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+
+Create supplier::
+
+ >>> supplier = Party(name='Suppier')
+ >>> supplier.save()
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+ >>> input_loc, = Location.find([('code', '=', 'IN')])
+
+Create new location::
+
+ >>> Location = Model.get('stock.location')
+ >>> child_loc = Location()
+ >>> child_loc.name = 'Child Location'
+ >>> child_loc.parent = storage_loc
+ >>> child_loc.code = 'CHI'
+ >>> child_loc.save()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template_location = template.locations.new()
+ >>> template_location.warehouse = warehouse_loc
+ >>> template_location.location = child_loc
+ >>> template.save()
+ >>> product, = template.products
+
+Create Shipment in::
+
+ >>> Shipmentin = Model.get('stock.shipment.in')
+ >>> shipment_in = Shipmentin()
+ >>> shipment_in.planned_date = today
+ >>> shipment_in.supplier = supplier
+ >>> shipment_in.warehouse = warehouse_loc
+ >>> shipment_in.company = company
+
+Add one shipment line of product::
+
+ >>> move = shipment_in.incoming_moves.new()
+ >>> move.product = product
+ >>> move.uom = unit
+ >>> move.quantity = 1
+ >>> move.from_location = supplier_loc
+ >>> move.to_location = input_loc
+ >>> move.company = company
+ >>> move.unit_price = Decimal('1')
+ >>> move.currency = company.currency
+ >>> shipment_in.save()
+
+Test that to_location is child location on reception::
+
+ >>> shipment_in.click('receive')
+ >>> move, = shipment_in.inventory_moves
+ >>> move.to_location == child_loc
+ True
+
+Create return shipment out::
+
+ >>> Shipment_out_Return = Model.get('stock.shipment.out.return')
+ >>> shipment_out_return = Shipment_out_Return()
+ >>> shipment_out_return.customer = customer
+ >>> shipment_out_return.save()
+
+Add one shipment return line::
+
+ >>> move = shipment_out_return.incoming_moves.new()
+ >>> move.product = product
+ >>> move.uom =unit
+ >>> move.quantity = 1
+ >>> move.from_location = customer_loc
+ >>> move.to_location = input_loc
+ >>> move.company = company
+ >>> move.unit_price = Decimal('1')
+ >>> move.currency = company.currency
+ >>> shipment_out_return.save()
+
+Test that to_location is child location on reception::
+
+ >>> shipment_out_return.click('receive')
+ >>> move, = shipment_out_return.inventory_moves
+ >>> move.to_location == child_loc
+ True
diff --git a/modules/stock_product_location/tests/test_module.py b/modules/stock_product_location/tests/test_module.py
new file mode 100644
index 0000000000..38eb668738
--- /dev/null
+++ b/modules/stock_product_location/tests/test_module.py
@@ -0,0 +1,13 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockProductLocationTestCase(ModuleTestCase):
+ 'Test StockProductLocation module'
+ module = 'stock_product_location'
+ extras = ['production']
+
+
+del ModuleTestCase
diff --git a/modules/stock_product_location/tests/test_scenario.py b/modules/stock_product_location/tests/test_scenario.py
new file mode 100644
index 0000000000..dc1d23e7e5
--- /dev/null
+++ b/modules/stock_product_location/tests/test_scenario.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import load_doc_tests
+
+
+def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_product_location/tox.ini b/modules/stock_product_location/tox.ini
new file mode 100644
index 0000000000..1b05d3f2f9
--- /dev/null
+++ b/modules/stock_product_location/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_product_location/* -m unittest discover -s tests
+ coverage report --include=./**/stock_product_location/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_product_location/tryton.cfg b/modules/stock_product_location/tryton.cfg
new file mode 100644
index 0000000000..95daefe1b4
--- /dev/null
+++ b/modules/stock_product_location/tryton.cfg
@@ -0,0 +1,11 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ product
+ stock
+extras_depend:
+ production
+xml:
+ location.xml
+ product.xml
diff --git a/modules/stock_product_location/view/product_form.xml b/modules/stock_product_location/view/product_form.xml
new file mode 100644
index 0000000000..ce0e38766f
--- /dev/null
+++ b/modules/stock_product_location/view/product_form.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_product_location/view/product_location_form.xml b/modules/stock_product_location/view/product_location_form.xml
new file mode 100644
index 0000000000..1fdab2ce11
--- /dev/null
+++ b/modules/stock_product_location/view/product_location_form.xml
@@ -0,0 +1,16 @@
+
+
+
diff --git a/modules/stock_product_location/view/product_location_tree.xml b/modules/stock_product_location/view/product_location_tree.xml
new file mode 100644
index 0000000000..8ecced7f17
--- /dev/null
+++ b/modules/stock_product_location/view/product_location_tree.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_quantity_early_planning/.drone.yml b/modules/stock_quantity_early_planning/.drone.yml
new file mode 100644
index 0000000000..b45ef267ef
--- /dev/null
+++ b/modules/stock_quantity_early_planning/.drone.yml
@@ -0,0 +1,78 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+ check_doc:
+ image: ${IMAGE}
+ commands:
+ - pip install sphinx
+ - python -m sphinx -T -E -W -n -b html doc _build/html
+ - python -m sphinx -T -E -W -n -b linkcheck doc _build
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_quantity_early_planning/.flake8 b/modules/stock_quantity_early_planning/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_quantity_early_planning/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_quantity_early_planning/.isort.cfg b/modules/stock_quantity_early_planning/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_quantity_early_planning/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_quantity_early_planning/CHANGELOG b/modules/stock_quantity_early_planning/CHANGELOG
new file mode 100644
index 0000000000..31ce9e29af
--- /dev/null
+++ b/modules/stock_quantity_early_planning/CHANGELOG
@@ -0,0 +1,20 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Prevent early planning of production missing moves
+* Compute early date for partial quantity of stock move
+* Add support for Python 3.10
+* Remove support for Python 3.6
+* Update early date base on internal incoming requests
+
+Version 6.2.0 - 2021-11-01
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+--------------------------
+* Initial release
diff --git a/modules/stock_quantity_early_planning/COPYRIGHT b/modules/stock_quantity_early_planning/COPYRIGHT
new file mode 100644
index 0000000000..48e43c6ea0
--- /dev/null
+++ b/modules/stock_quantity_early_planning/COPYRIGHT
@@ -0,0 +1,14 @@
+Copyright (C) 2021-2022 Cédric Krier
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_quantity_early_planning/LICENSE b/modules/stock_quantity_early_planning/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_quantity_early_planning/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_quantity_early_planning/MANIFEST.in b/modules/stock_quantity_early_planning/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_quantity_early_planning/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_quantity_early_planning/README.rst b/modules/stock_quantity_early_planning/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_quantity_early_planning/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_quantity_early_planning/__init__.py b/modules/stock_quantity_early_planning/__init__.py
new file mode 100644
index 0000000000..41ff3a89cd
--- /dev/null
+++ b/modules/stock_quantity_early_planning/__init__.py
@@ -0,0 +1,23 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import stock
+
+__all__ = ['register']
+
+
+def register():
+ Pool.register(
+ stock.QuantityEarlyPlan,
+ stock.Move,
+ stock.QuantityEarlyPlanGenerateStart,
+ module='stock_quantity_early_planning', type_='model')
+ Pool.register(
+ stock.QuantityEarlyPlanGenerate,
+ module='stock_quantity_early_planning', type_='wizard')
+ Pool.register(
+ stock.QuantityEarlyPlanProduction,
+ module='stock_quantity_early_planning', type_='model',
+ depends=['production'])
diff --git a/modules/stock_quantity_early_planning/doc/conf.py b/modules/stock_quantity_early_planning/doc/conf.py
new file mode 100644
index 0000000000..8513b72dd2
--- /dev/null
+++ b/modules/stock_quantity_early_planning/doc/conf.py
@@ -0,0 +1,61 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+modules_url = 'https://docs.tryton.org/projects/modules-{module}/en/{series}/'
+trytond_url = 'https://docs.tryton.org/projects/server/en/{series}/'
+
+
+def get_info():
+ import configparser
+ import os
+ import subprocess
+ import sys
+
+ module_dir = os.path.dirname(os.path.dirname(__file__))
+
+ config = configparser.ConfigParser()
+ config.read_file(open(os.path.join(module_dir, 'tryton.cfg')))
+ info = dict(config.items('tryton'))
+
+ result = subprocess.run(
+ [sys.executable, 'setup.py', '--name'],
+ stdout=subprocess.PIPE, check=True, cwd=module_dir)
+ info['name'] = result.stdout.decode('utf-8').strip()
+
+ result = subprocess.run(
+ [sys.executable, 'setup.py', '--version'],
+ stdout=subprocess.PIPE, check=True, cwd=module_dir)
+ version = result.stdout.decode('utf-8').strip()
+ if 'dev' in version:
+ info['series'] = 'latest'
+ else:
+ info['series'] = '.'.join(version.split('.', 2)[:2])
+
+ for key in {'depends', 'extras_depend'}:
+ info[key] = info.get(key, '').strip().splitlines()
+ info['modules'] = set(info['depends'] + info['extras_depend'])
+ info['modules'] -= {'ir', 'res'}
+
+ return info
+
+
+info = get_info()
+
+master_doc = 'index'
+project = info['name']
+release = version = info['series']
+default_role = 'ref'
+highlight_language = 'none'
+extensions = [
+ 'sphinx.ext.intersphinx',
+ ]
+intersphinx_mapping = {
+ 'trytond': (trytond_url.format(series=version), None),
+ }
+intersphinx_mapping.update({
+ m: (modules_url.format(
+ module=m.replace('_', '-'), series=version), None)
+ for m in info['modules']
+ })
+
+del get_info, info, modules_url, trytond_url
diff --git a/modules/stock_quantity_early_planning/doc/design.rst b/modules/stock_quantity_early_planning/doc/design.rst
new file mode 100644
index 0000000000..0c8a81f0c2
--- /dev/null
+++ b/modules/stock_quantity_early_planning/doc/design.rst
@@ -0,0 +1,53 @@
+******
+Design
+******
+
+The *Stock Quantity Early Planning* introduces the following concepts:
+
+.. _model-stock.quantity.early_plan:
+
+Stock Quantity Early Plan
+=========================
+
+*Quantity Early Plannings* are generated by the `wizard
+` of the same name.
+They represent possible planning optimisation regarding the quantity of stock
+available for future `Shipments `,
+:doc:`Productions ` or `Outgoing Moves
+`.
+
+Possible early dates are calculated for the planning.
+Ignoring the proposal makes that the system will no more create proposal for
+the origin.
+
+The `Employee ` who processes, closes or
+ignores the planning is recorded.
+
+.. seealso::
+
+ Quantity Early Planning can be found by opening the main menu item:
+
+ |Inventory & Stock --> Quantity Early Planning|__
+
+ .. |Inventory & Stock --> Quantity Early Planning| replace:: :menuselection:`Inventory & Stock --> Quantity Early Planning`
+ __ https://demo.tryton.org/model/stock.quantity.early_plan
+
+Wizards
+-------
+
+.. _wizard-stock.quantity.early_plan.generate:
+
+Generate Stock Quantity Early Planning
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The *Generate Stock Quantity Early Plannings* wizard creates for each warehouse
+the `Stock Quantity Early Plans ` if there are
+possibilities.
+When running it deletes any open plans, updates the processing and
+plans with new moves and create new plans.
+
+.. seealso::
+
+ The wizard can be launched by opening:
+
+ :menuselection:`Inventory & Stock --> Quantity Early Planning --> Generate`
diff --git a/modules/stock_quantity_early_planning/doc/index.rst b/modules/stock_quantity_early_planning/doc/index.rst
new file mode 100644
index 0000000000..6481f3ab1a
--- /dev/null
+++ b/modules/stock_quantity_early_planning/doc/index.rst
@@ -0,0 +1,13 @@
+####################################
+Stock Quantity Early Planning Module
+####################################
+
+The *Stock Quantity Early Planning Module* helps reducing stock level by
+proposing to consume earlier.
+
+.. toctree::
+ :maxdepth: 2
+
+ usage
+ design
+ releases
diff --git a/modules/stock_quantity_early_planning/doc/releases.rst b/modules/stock_quantity_early_planning/doc/releases.rst
new file mode 100644
index 0000000000..21b13c4745
--- /dev/null
+++ b/modules/stock_quantity_early_planning/doc/releases.rst
@@ -0,0 +1,7 @@
+.. _releases-index:
+
+=============
+Release notes
+=============
+
+.. include:: ../CHANGELOG
diff --git a/modules/stock_quantity_early_planning/doc/usage.rst b/modules/stock_quantity_early_planning/doc/usage.rst
new file mode 100644
index 0000000000..1a81c3aece
--- /dev/null
+++ b/modules/stock_quantity_early_planning/doc/usage.rst
@@ -0,0 +1,12 @@
+*****
+Usage
+*****
+
+.. _Generate stock quantity early planning:
+
+Generate stock quantity early planning
+======================================
+
+You can run the wizard `Generate Stock Quantity Early Planning
+` at any time to calculate or update
+the planning.
diff --git a/modules/stock_quantity_early_planning/locale/bg.po b/modules/stock_quantity_early_planning/locale/bg.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/bg.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/ca.po b/modules/stock_quantity_early_planning/locale/ca.po
new file mode 100644
index 0000000000..63a2e90bb5
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/ca.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr "Planificacions de disponiblitat anticipada"
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr "Tancat per"
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr "Última data"
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr "Primera data"
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr "Percentage primera data"
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr "Data anticipada"
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr "Quantitat anticipada"
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr "Ignorat per"
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr "Moviments"
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr "Origen"
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr "Data estimada"
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr "Processat per"
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr "Estat"
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr "Magatzem"
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr "Magatzems"
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr "Si es deixa en blanc s'utilitzen tots els magatzems."
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr "Planificació de disponiblitat anticipada"
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr "Genera planificacions de disponiblitat anticipada"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr "Tot"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr "Obert"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr "En procés"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr "Tanca"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr "Ignora"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr "Restableix a obert"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr "Processa"
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr "Usuari a les empreses"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr "Planificació de disponiblitat anticipada"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr "Genera planificacions de disponiblitat anticipada"
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr "Planificació de disponiblitat anticipada"
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr "Genera planificació de disponiblitat anticipada"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr "Tancat"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr "Ignorat"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr "Obert"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr "En procés"
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr "Generar planificació de disponiblitat anticipada?"
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr "Informació addicional"
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr "Cancel·la"
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr "Genera"
diff --git a/modules/stock_quantity_early_planning/locale/cs.po b/modules/stock_quantity_early_planning/locale/cs.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/cs.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/de.po b/modules/stock_quantity_early_planning/locale/de.po
new file mode 100644
index 0000000000..575c94a55f
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/de.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr "Pläne Frühere Verfügbarkeit"
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr "Geschlossen von"
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr "Unternehmen"
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr "Früheres Datum"
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr "Frühestes Datum"
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr "Prozentsatz zum frühesten Zeitpunkt"
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr "Früheres Datum"
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr "Vorgezogene Menge"
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr "Ignoriert von"
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr "Warenbewegungen"
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr "Herkunft"
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr "Geplantes Datum"
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr "Bearbeitet von"
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr "Status"
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr "Logistikstandort"
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr "Logistikstandorte"
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr "Leer lassen, um alle Logistikstandorte zu verwenden."
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr "Planung Frühere Verfügbarkeit"
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr "Planung Frühere Verfügbarkeit Generieren"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr "Alle"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr "Offen"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr "In Ausführung"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr "Schließen"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr "Ignorieren"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr "Wiedereröffnen"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr "Ausführen"
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr "Benutzer im Unternehmen"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr "Planung Frühere Verfügbarkeit"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr "Planung Frühere Verfügbarkeit Erstellen"
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr "Lager Plan Frühere Verfügbarkeit"
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr "Lager Plan Frühere Verfügbarkeit Erstellen"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr "Geschlossen"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr "Ignoriert"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr "Offen"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr "In Ausführung"
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr "Planung Frühere Verfügbarkeit erstellen?"
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr "Sonstiges"
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr "Abbrechen"
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr "Erstellen"
diff --git a/modules/stock_quantity_early_planning/locale/es.po b/modules/stock_quantity_early_planning/locale/es.po
new file mode 100644
index 0000000000..28a2ddb619
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/es.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr "Planificaciones de disponiblidad anticipada"
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr "Cerrado por"
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr "Última fecha"
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr "Primera fecha"
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr "Porcentaje primera fecha"
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr "Fecha anticipada"
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr "Cantidad anticipada"
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr "Ignorado por"
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr "Movimientos"
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr "Origen"
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr "Fecha estimada"
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr "Procesado por"
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr "Estado"
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr "Almacén"
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr "Almacenes"
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr "Si está vacío se utilizan todos los almacenes."
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr "Planificación de disponiblidad anticipada"
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr "Generar planificaciones de disponiblidad anticipada"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr "Todo"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr "Abierto"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr "En proceso"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr "Cerrar"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr "Ignorar"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr "Restablecer a abierto"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr "Procesar"
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr "Usuario en las empresas"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr "Planificación de disponiblidad anticipada"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr "Generar planificaciones de disponiblidad anticipada"
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr "Planificación de disponiblidad anticipada"
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr "Generar planificación de disponiblidad anticipada"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr "Cerrado"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr "Ignorado"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr "Abierto"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr "En proceso"
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr "¿Generar planificación de disponiblidad anticipada?"
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr "Información adicional"
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr "Generar"
diff --git a/modules/stock_quantity_early_planning/locale/es_419.po b/modules/stock_quantity_early_planning/locale/es_419.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/es_419.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/et.po b/modules/stock_quantity_early_planning/locale/et.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/et.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/fa.po b/modules/stock_quantity_early_planning/locale/fa.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/fa.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/fi.po b/modules/stock_quantity_early_planning/locale/fi.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/fi.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/fr.po b/modules/stock_quantity_early_planning/locale/fr.po
new file mode 100644
index 0000000000..de63ed7c9b
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/fr.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr "Plans anticipés de quantité"
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr "Fermé par"
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr "Société"
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr "Date antérieure"
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr "Date au plus tôt"
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr "Pourcentage au plus tôt"
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr "Date en avance"
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr "Quantité en avance"
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr "Ignoré par"
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr "Mouvements"
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr "Origine"
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr "Date planifiée"
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr "Traité par"
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr "État"
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr "Entrepôt"
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr "Entrepôts"
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr "Si vide, tous les entrepôts sont utilisés."
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr "Planification en avance des quantités"
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr "Générer une planification en avance des quantités de stock"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr "Tous"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr "Ouverts"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr "En traitement"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr "Fermer"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr "Ignorer"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr "Réinitialiser pour ouvrir"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr "Traiter"
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr "Utilisateur dans les sociétés"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr "Planification en avance des quantités"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr "Générer une planification en avance des quantités de stock"
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr "Plan en avance des quantités de stock"
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr "Générer un plan en avance des quantités de stock"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr "Fermé"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr "Ignoré"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr "Ouvert"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr "En traitement"
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr "Générer une planification en avance des quantités de stock ?"
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr "Autre information"
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr "Annuler"
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr "Générer"
diff --git a/modules/stock_quantity_early_planning/locale/hu.po b/modules/stock_quantity_early_planning/locale/hu.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/hu.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/id.po b/modules/stock_quantity_early_planning/locale/id.po
new file mode 100644
index 0000000000..c2e35f64f0
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/id.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr "Perusahaan"
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr "Asal"
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr "Tutup"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr "Proses"
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr "Pengguna di dalam perusahaan"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr "Info Lain"
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr "Batal"
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/it.po b/modules/stock_quantity_early_planning/locale/it.po
new file mode 100644
index 0000000000..9db9d4e9fa
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/it.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr "Origine"
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr "Magazzino"
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr "Magazzini"
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/lo.po b/modules/stock_quantity_early_planning/locale/lo.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/lo.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/lt.po b/modules/stock_quantity_early_planning/locale/lt.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/lt.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/nl.po b/modules/stock_quantity_early_planning/locale/nl.po
new file mode 100644
index 0000000000..73c9c3acf9
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/nl.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr "Hoeveelheid vroege planning"
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr "Gesloten door"
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr "Bedrijf"
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr "Eerdere datum"
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr "Vroegste datum"
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr "Vroegste percentage"
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr "Eerdere datum"
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr "Vroege hoeveelheid"
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr "Genegeerd door"
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr "Mutaties"
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr "Oorsprong(herkomst)"
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr "Geplande datum"
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr "Verwerkt door"
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr "Status"
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr "Magazijn"
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr "Magazijnen"
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr "Indien leeg worden alle magazijnen gebruikt."
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr "Vooraf plannen van hoeveelheden"
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr "Genereer voorraadhoeveelheid Vroege planning"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr "Alle"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr "Open"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr "Verwerken"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr "Sluiten"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr "Negeren"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr "Resetten om te openen"
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr "Uitvoeren"
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr "Gebruiker in het bedrijf"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr "Vooraf plannen van hoeveelheden"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr "Genereer voorraadhoeveelheid Vroege planning"
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr "Plan vooruit op voorraadhoeveelheden"
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr "Voorraadhoeveelheid Vroeg plan Genereren"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr "Afgesloten"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr "Genegeerd"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr "Open"
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr "Verwerken"
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr "Genereer voorraadhoeveelheid Vroege planning?"
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr "Overige informatie"
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr "Annuleer"
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr "Genereer"
diff --git a/modules/stock_quantity_early_planning/locale/pl.po b/modules/stock_quantity_early_planning/locale/pl.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/pl.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/pt.po b/modules/stock_quantity_early_planning/locale/pt.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/pt.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/ro.po b/modules/stock_quantity_early_planning/locale/ro.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/ro.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/ru.po b/modules/stock_quantity_early_planning/locale/ru.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/ru.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/sl.po b/modules/stock_quantity_early_planning/locale/sl.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/sl.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/tr.po b/modules/stock_quantity_early_planning/locale/tr.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/tr.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/uk.po b/modules/stock_quantity_early_planning/locale/uk.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/uk.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/locale/zh_CN.po b/modules/stock_quantity_early_planning/locale/zh_CN.po
new file mode 100644
index 0000000000..7365f69abb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/locale/zh_CN.po
@@ -0,0 +1,162 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,quantity_early_plans:"
+msgid "Quantity Early Plans"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,closed_by:"
+msgid "Closed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earlier_date:"
+msgid "Earlier Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_date:"
+msgid "Earliest Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,earliest_percentage:"
+msgid "Earliest Percentage"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_date:"
+msgid "Early Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,early_quantity:"
+msgid "Early Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,ignored_by:"
+msgid "Ignored by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.quantity.early_plan.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_early_plan_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_close_button"
+msgid "Close"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_ignore_button"
+msgid "Ignore"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_early_plan_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_early_plan_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_form"
+msgid "Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_early_plan_generate"
+msgid "Generate Stock Quantity Early Planning"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan,name:"
+msgid "Stock Quantity Early Plan"
+msgstr ""
+
+msgctxt "model:stock.quantity.early_plan.generate.start,name:"
+msgid "Stock Quantity Early Plan Generate"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Closed"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Ignored"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.early_plan,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan.generate.start:"
+msgid "Generate Stock Quantity Early Planning?"
+msgstr ""
+
+msgctxt "view:stock.quantity.early_plan:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.early_plan.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_early_planning/setup.py b/modules/stock_quantity_early_planning/setup.py
new file mode 100755
index 0000000000..e3ebf47fb9
--- /dev/null
+++ b/modules/stock_quantity_early_planning/setup.py
@@ -0,0 +1,161 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ content = io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+ content = re.sub(
+ r'(?m)^\.\. toctree::\r?\n((^$|^\s.*$)\r?\n)*', '', content)
+ return content
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_quantity_early_planning'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+requires = []
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [
+ 'python-dateutil',
+ get_require_version('proteus'),
+ get_require_version('trytond_production'),
+ ]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version)
+ )
+
+setup(name=name,
+ version=version,
+ description='Tryton module to plan earlier shipments and productions',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": ('https://docs.tryton.org/projects/'
+ 'modules-stock-quantity-early-planning'),
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": ('https://hg.tryton.org/modules/'
+ 'stock_quantity_early_planning'),
+ },
+ keywords='tryton stock planning shipment production',
+ package_dir={'trytond.modules.stock_quantity_early_planning': '.'},
+ packages=(
+ ['trytond.modules.stock_quantity_early_planning']
+ + ['trytond.modules.stock_quantity_early_planning.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_quantity_early_planning': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_quantity_early_planning = trytond.modules.stock_quantity_early_planning
+ """, # noqa: E501
+ )
diff --git a/modules/stock_quantity_early_planning/stock.py b/modules/stock_quantity_early_planning/stock.py
new file mode 100644
index 0000000000..0519c0b9f4
--- /dev/null
+++ b/modules/stock_quantity_early_planning/stock.py
@@ -0,0 +1,590 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import datetime as dt
+from collections import defaultdict
+from itertools import groupby
+
+from trytond.model import Index, Model, ModelSQL, ModelView, Workflow, fields
+from trytond.modules.company.model import (
+ employee_field, reset_employee, set_employee)
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Eval
+from trytond.transaction import Transaction
+from trytond.wizard import Button, StateAction, StateView, Wizard
+
+
+class QuantityEarlyPlan(Workflow, ModelSQL, ModelView):
+ "Stock Quantity Early Plan"
+ __name__ = 'stock.quantity.early_plan'
+
+ company = fields.Many2One(
+ 'company.company', "Company", required=True)
+ origin = fields.Reference(
+ "Origin", 'get_origins', required=True,
+ domain={
+ 'stock.move': [
+ ('company', '=', Eval('company', -1)),
+ ],
+ 'stock.shipment.out': [
+ ('company', '=', Eval('company', -1)),
+ ],
+ 'stock.shipment.in.return': [
+ ('company', '=', Eval('company', -1)),
+ ],
+ 'stock.shipment.internal': [
+ ('company', '=', Eval('company', -1)),
+ ],
+ })
+ planned_date = fields.Function(
+ fields.Date("Planned Date"),
+ 'on_change_with_planned_date')
+ early_quantity = fields.Float(
+ "Early Quantity", readonly=True,
+ states={
+ 'invisible': True,
+ })
+ early_date = fields.Date(
+ "Early Date", readonly=True,
+ states={
+ 'invisible': True,
+ })
+ earlier_date = fields.Function(
+ fields.Date("Earlier Date"), 'get_earlier_date')
+ earliest_date = fields.Function(
+ fields.Date("Earliest Date"), 'get_earliest_date')
+ earliest_percentage = fields.Function(
+ fields.Float(
+ "Earliest Percentage", digits=(1, 4),
+ states={
+ 'invisible': ~Eval('earliest_date'),
+ }),
+ 'get_earliest_percentage')
+ warehouse = fields.Function(
+ fields.Many2One('stock.location', "Warehouse"),
+ 'on_change_with_warehouse')
+ moves = fields.Function(
+ fields.One2Many(
+ 'stock.quantity.early_plan', None, "Moves",
+ states={
+ 'invisible': ~Eval('moves'),
+ }),
+ 'get_moves')
+
+ processed_by = employee_field("Processed by", states=['processing'])
+ closed_by = employee_field("Closed by", states=['closed'])
+ ignored_by = employee_field("Ignored by", states=['ignored'])
+
+ state = fields.Selection([
+ ('open', "Open"),
+ ('processing', "Processing"),
+ ('closed', "Closed"),
+ ('ignored', "Ignored"),
+ ], "State", required=True, readonly=True, sort=False)
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ t = cls.__table__()
+ cls._sql_indexes.add(
+ Index(
+ t,
+ (t.state, Index.Equality()),
+ where=t.state.in_(['open', 'processing'])))
+ cls._transitions |= {
+ ('open', 'processing'),
+ ('open', 'ignored'),
+ ('processing', 'closed'),
+ ('processing', 'open'),
+ ('processing', 'ignored'),
+ ('ignored', 'open'),
+ }
+ cls._buttons.update({
+ 'open': {
+ 'invisible': ~Eval('state').in_(['processing', 'ignored']),
+ 'depends': ['state'],
+ },
+ 'process': {
+ 'invisible': Eval('state') != 'open',
+ 'depends': ['state'],
+ },
+ 'close': {
+ 'invisible': Eval('state') != 'processing',
+ 'depends': ['state'],
+ },
+ 'ignore': {
+ 'invisible': ~Eval('state').in_(['open', 'processing']),
+ 'depends': ['state'],
+ },
+ })
+
+ @classmethod
+ def get_origins(cls):
+ pool = Pool()
+ Model = pool.get('ir.model')
+ get_name = Model.get_name
+ models = cls._get_origins()
+ return [(m, get_name(m)) for m in models]
+
+ @classmethod
+ def _get_origins(cls):
+ "Return a list of Model names for origin Reference"
+ return [
+ 'stock.move',
+ 'stock.shipment.out',
+ 'stock.shipment.in.return',
+ 'stock.shipment.internal',
+ ]
+
+ @fields.depends('origin')
+ def on_change_with_planned_date(self, name=None):
+ if isinstance(self.origin, Model) and self.origin.id >= 0:
+ return self.origin.planned_date
+
+ def get_earlier_date(self, name):
+ return self._get_dates(max)
+
+ def get_earliest_date(self, name):
+ return self._get_dates(min)
+
+ @property
+ def _allow_partial_moves(self):
+ "Allow to early planning without all moves"
+ return True
+
+ def _get_dates(self, aggregate):
+ pool = Pool()
+ Move = pool.get('stock.move')
+ if isinstance(self.origin, Move) and self.origin.id >= 0:
+ if (aggregate == max
+ and self.early_quantity != self.origin.internal_quantity):
+ return self.origin.planned_date
+ else:
+ return self.early_date
+ elif (not self._allow_partial_moves
+ and any(not m.early_date for m in self.moves)):
+ return self.planned_date
+ else:
+ return aggregate(
+ filter(None, (m._get_dates(aggregate) for m in self.moves)),
+ default=self.planned_date)
+
+ @property
+ def _early_quantity(self):
+ if isinstance(self.origin, Move) and self.origin.id >= 0:
+ if self.early_quantity is not None:
+ return self.early_quantity
+ else:
+ return self.origin.internal_quantity
+
+ def get_earliest_percentage(self, name):
+ pool = Pool()
+ Move = pool.get('stock.move')
+ if isinstance(self.origin, Move) and self.origin.id >= 0:
+ return round(
+ self._early_quantity / self.origin.internal_quantity, 4)
+ else:
+ date = self._get_dates(min)
+ total = sum(m.origin.internal_quantity for m in self.moves)
+ quantity = sum(
+ m._early_quantity for m in self.moves
+ if (m.early_date or m.planned_date or dt.date.max) <= date)
+ if total:
+ return round(quantity / total, 4)
+ else:
+ return 1
+
+ @classmethod
+ def default_warehouse(cls):
+ pool = Pool()
+ Location = pool.get('stock.location')
+ return Location.get_default_warehouse()
+
+ @fields.depends('origin')
+ def on_change_with_warehouse(self, name=None):
+ pool = Pool()
+ Move = pool.get('stock.move')
+ if isinstance(self.origin, Move) and self.origin.id >= 0:
+ warehouse = self.origin.from_location.warehouse
+ if warehouse:
+ return warehouse.id
+ elif (isinstance(self.origin, Model) and self.origin.id >= 0
+ and getattr(self.origin, 'warehouse', None)):
+ return self.origin.warehouse.id
+
+ def get_moves(self, name):
+ pool = Pool()
+ ShipmentOut = pool.get('stock.shipment.out')
+ ShipmentInReturn = pool.get('stock.shipment.in.return')
+ ShipmentInternal = pool.get('stock.shipment.internal')
+ moves = []
+ if isinstance(self.origin, (
+ ShipmentOut, ShipmentInReturn, ShipmentInternal)):
+ for move in self.origin.moves:
+ moves.extend([p.id for p in move.quantity_early_plans])
+ return moves
+
+ @classmethod
+ def default_state(cls):
+ return 'open'
+
+ def get_rec_name(self, name):
+ return (self.origin.rec_name if isinstance(self.origin, Model)
+ else '(%s)' % self.id)
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('open')
+ @reset_employee('processed_by', 'ignored_by')
+ def open(cls, plans):
+ pass
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('processing')
+ @set_employee('processed_by')
+ def process(cls, plans):
+ pass
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('closed')
+ @set_employee('closed_by')
+ def close(cls, plans):
+ pass
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('ignored')
+ @set_employee('ignored_by')
+ def ignore(cls, plans):
+ pass
+
+ @classmethod
+ def generate_plans(cls, warehouses=None, company=None):
+ """
+ For each outgoing move it creates an early plan and a plan for its
+ shipment.
+
+ If warehouses is specified it searches only for moves from them.
+ """
+ pool = Pool()
+ Date = pool.get('ir.date')
+ Location = pool.get('stock.location')
+ Move = pool.get('stock.move')
+ User = pool.get('res.user')
+
+ if warehouses is None:
+ warehouses = Location.search([
+ ('type', '=', 'warehouse'),
+ ])
+ if company is None:
+ company = User(Transaction().user).company
+
+ with Transaction().set_context(company=company.id):
+ today = Date.today()
+
+ # Do not keep former plan as the may no more be valid
+ opens = cls.search([
+ ('company', '=', company.id),
+ ('state', '=', 'open'),
+ ])
+ opens = [
+ p for p in opens if p.warehouse in warehouses or not p.warehouse]
+ cls.delete(opens)
+
+ plans = {}
+ for plan in cls.search([
+ ('company', '=', company.id),
+ ('state', 'in', ['processing', 'ignored']),
+ ]):
+ if plan.warehouse not in warehouses:
+ continue
+ plans[plan.origin] = plan
+
+ for warehouse in warehouses:
+ moves = Move.search([
+ ('company', '=', company.id),
+ ('from_location', 'child_of', [warehouse.id], 'parent'),
+ ('to_location', 'not child_of', [warehouse.id], 'parent'),
+ ('planned_date', '>', today),
+ ('state', '=', 'draft'),
+ ],
+ order=[('product.id', 'ASC'), ('planned_date', 'ASC')])
+
+ for product, moves in groupby(moves, lambda m: m.product):
+ for move in moves:
+ earlier_date, quantity = cls._get_earlier_date(
+ move, warehouse)
+ plan = cls._add(move, plans)
+ if earlier_date < move.planned_date:
+ plan.early_date = earlier_date
+ else:
+ plan.early_date = None
+ plan.early_quantity = quantity
+
+ for parent in cls._parents(move):
+ cls._add(parent, plans)
+ cls.save(plans.values())
+
+ to_delete = []
+ for plan in cls.browse(plans.values()):
+ if (plan.state == 'open'
+ and not isinstance(plan.origin, Move)
+ and plan.earliest_date == plan.planned_date):
+ to_delete.append(plan)
+ cls.delete(to_delete)
+
+ # Update early date based on internal incoming requests
+ for warehouse in warehouses:
+ product_plans = cls.search([
+ ('company', '=', company.id),
+ ('state', '=', 'open'),
+ ('origin', 'like', 'stock.move,%'),
+ ],
+ order=[('early_date', 'ASC NULLS LAST')])
+
+ in_plans = cls.search([
+ ('company', '=', company.id),
+ ('state', 'in', ['open', 'processing']),
+ cls._incoming_domain(),
+ ])
+ product2in = defaultdict(lambda: defaultdict(list))
+ for plan in in_plans:
+ products = defaultdict(int)
+ for product, quantity in plan._incoming_quantities(warehouse):
+ products[product] += quantity
+ for product, quantity in products.items():
+ product2in[product][plan.planned_date].append(
+ (quantity, plan))
+
+ to_save = []
+ products = set()
+ for product_plan in product_plans:
+ if product_plan.warehouse != warehouse:
+ continue
+ product = product_plan.origin.product
+ quantity = product_plan.origin.internal_quantity
+ plans = product2in[product][product_plan.early_date]
+ plans = cls._pick_incoming(quantity, plans)
+ if plans:
+ incoming_products = {p
+ for pl in plans
+ for p, q in pl._incoming_quantities(warehouse)}
+ if incoming_products & products:
+ cls.save(to_save)
+ del to_save[:]
+ products.clear()
+
+ earlier_date = max(p.earlier_date for p in plans)
+
+ if (not product_plan.early_date
+ or product_plan.early_date > earlier_date):
+ product_plan.early_date = earlier_date
+ to_save.append(product_plan)
+ products.add(product)
+ cls.save(to_save)
+
+ @classmethod
+ def _get_earlier_date(cls, move, warehouse):
+ pool = Pool()
+ Date = pool.get('ir.date')
+ ProductQuantitiesByWarehouse = pool.get(
+ 'stock.product_quantities_warehouse')
+ product = move.product
+ with Transaction().set_context(company=move.company.id):
+ today = Date.today()
+
+ quantity = move.internal_quantity
+ if product.consumable:
+ return today, quantity
+
+ with Transaction().set_context(
+ product=product.id,
+ warehouse=warehouse.id,
+ stock_skip_warehouse=False,
+ ):
+ product_quantities = (
+ ProductQuantitiesByWarehouse.search([
+ ('date', '>=', today),
+ ('date', '<=', move.planned_date),
+ ],
+ order=[('date', 'DESC')]))
+ future_product_quantities = (
+ ProductQuantitiesByWarehouse.search([
+ ('date', '>=', move.planned_date),
+ ]))
+ min_future_product_quantity = min(
+ p.quantity for p in future_product_quantities)
+ earlier_date = move.planned_date
+ if product_quantities and product_quantities[0].quantity >= 0:
+ assert product_quantities[0].date == move.planned_date
+ if product_quantities[0].quantity > -quantity:
+ # The new date must left the same available
+ # quantity for other moves at the current date
+ min_quantity = (
+ product_quantities[0].quantity
+ + move.internal_quantity)
+ quantity = min(min_quantity, move.internal_quantity)
+ if min_future_product_quantity > 0:
+ # The remaining quantities can be used
+ min_quantity -= min_future_product_quantity
+ if quantity >= 0:
+ for product_quantity in product_quantities[1:]:
+ if product_quantity.quantity < min_quantity:
+ if earlier_date == move.planned_date:
+ # Not found earlier date,
+ # try with the first smaller quantity
+ quantity = min(
+ quantity, product_quantity.quantity)
+ min_quantity = min(
+ product_quantity.quantity,
+ move.internal_quantity)
+ else:
+ break
+ earlier_date = product_quantity.date
+ return earlier_date, quantity
+
+ @classmethod
+ def _add(cls, origin, plans):
+ if origin in plans:
+ plan = plans[origin]
+ else:
+ plan = plans[origin] = cls(
+ company=origin.company,
+ origin=origin)
+ return plan
+
+ @classmethod
+ def _parents(cls, move):
+ if move.shipment:
+ yield move.shipment
+
+ @classmethod
+ def _incoming_domain(cls):
+ return ['OR',
+ ('origin.state', '=', 'request', 'stock.shipment.internal'),
+ ]
+
+ def _incoming_quantities(self, warehouse):
+ pool = Pool()
+ ShipmentInternal = pool.get('stock.shipment.internal')
+ if isinstance(self.origin, ShipmentInternal):
+ shipment = self.origin
+ if (shipment.to_location.warehouse == warehouse
+ or shipment.from_location.warehouse != warehouse):
+ for move in shipment.moves:
+ if move.to_location.warehouse == warehouse:
+ yield move.product, move.internal_quantity
+
+ @classmethod
+ def _pick_incoming(cls, quantity, plans):
+ plans = [p for q, p in plans if q >= quantity]
+ plans.sort(key=lambda p: p.earlier_date)
+ return plans
+
+
+class QuantityEarlyPlanProduction(metaclass=PoolMeta):
+ __name__ = 'stock.quantity.early_plan'
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls.origin.domain['production'] = [
+ ('company', '=', Eval('company', -1)),
+ ]
+
+ @classmethod
+ def _get_origins(cls):
+ return super()._get_origins() + ['production']
+
+ @property
+ def _allow_partial_moves(self):
+ pool = Pool()
+ Production = pool.get('production')
+ allow = super()._allow_partial_moves
+ if (isinstance(self.origin, Production)
+ and any(not m.early_date for m in self.moves)):
+ allow = False
+ return allow
+
+ def get_moves(self, name):
+ pool = Pool()
+ Production = pool.get('production')
+ moves = super().get_moves(name)
+ if isinstance(self.origin, Production):
+ for move in self.origin.inputs + self.origin.outputs:
+ moves.extend([p.id for p in move.quantity_early_plans])
+ return moves
+
+ @classmethod
+ def _parents(cls, move):
+ yield from super()._parents(move)
+ if move.production_input:
+ yield move.production_input
+ if move.production_output:
+ yield move.production_output
+
+ @classmethod
+ def _incoming_domain(cls):
+ return super()._incoming_domain() + [
+ ('origin.state', '=', 'request', 'production'),
+ ]
+
+ def _incoming_quantities(self, warehouse):
+ pool = Pool()
+ Production = pool.get('production')
+ yield from super()._incoming_quantities(warehouse)
+ if isinstance(self.origin, Production):
+ production = self.origin
+ if production.warehouse == warehouse:
+ for output in production.outputs:
+ yield output.product, output.internal_quantity
+
+
+class Move(metaclass=PoolMeta):
+ __name__ = 'stock.move'
+
+ quantity_early_plans = fields.One2Many(
+ 'stock.quantity.early_plan', 'origin',
+ "Quantity Early Plans", readonly=True,
+ order=[('early_date', 'ASC NULLS LAST')])
+
+
+class QuantityEarlyPlanGenerate(Wizard):
+ "Stock Quantity Early Plan Generate"
+ __name__ = 'stock.quantity.early_plan.generate'
+ start = StateView(
+ 'stock.quantity.early_plan.generate.start',
+ 'stock_quantity_early_planning'
+ '.quantity_early_plan_generate_start_view_form', [
+ Button("Cancel", 'end', 'tryton-cancel'),
+ Button("Generate", 'generate', 'tryton-ok', default=True),
+ ])
+ generate = StateAction(
+ 'stock_quantity_early_planning.act_quantity_early_plan_form')
+
+ def transition_generate(self):
+ pool = Pool()
+ QuantityEarlyPlan = pool.get('stock.quantity.early_plan')
+ QuantityEarlyPlan.generate_plans(
+ warehouses=self.start.warehouses or None)
+ return 'end'
+
+
+class QuantityEarlyPlanGenerateStart(ModelView):
+ "Stock Quantity Early Plan Generate"
+ __name__ = 'stock.quantity.early_plan.generate.start'
+ warehouses = fields.Many2Many(
+ 'stock.location', None, None, "Warehouses",
+ domain=[
+ ('type', '=', 'warehouse'),
+ ],
+ help="If empty all warehouses are used.")
+
+ @classmethod
+ def default_warehouses(cls):
+ pool = Pool()
+ Location = pool.get('stock.location')
+ warehouse = Location.get_default_warehouse()
+ if warehouse:
+ return [warehouse]
diff --git a/modules/stock_quantity_early_planning/stock.xml b/modules/stock_quantity_early_planning/stock.xml
new file mode 100644
index 0000000000..20286ed1e3
--- /dev/null
+++ b/modules/stock_quantity_early_planning/stock.xml
@@ -0,0 +1,136 @@
+
+
+
+
+
+ stock.quantity.early_plan
+ form
+ quantity_early_plan_form
+
+
+
+ stock.quantity.early_plan
+ tree
+ quantity_early_plan_list
+
+
+
+ Quantity Early Planning
+ stock.quantity.early_plan
+
+
+
+
+
+
+
+
+
+
+
+
+ Open
+
+
+
+
+
+
+ Processing
+
+
+
+
+
+
+ All
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ User in companies
+
+
+
+
+
+
+
+
+
+ open
+ Reset to Open
+
+
+
+
+ process
+ Process
+
+
+
+
+ close
+ Close
+
+
+
+
+ ignore
+ Ignore
+
+
+
+
+ Generate Stock Quantity Early Planning
+ stock.quantity.early_plan.generate
+
+
+
+
+
+
+
+
+
+
+
+
+
+ stock.quantity.early_plan.generate.start
+ form
+ quantity_early_plan_generate_start_form
+
+
+
diff --git a/modules/stock_quantity_early_planning/tests/__init__.py b/modules/stock_quantity_early_planning/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_quantity_early_planning/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_quantity_early_planning/tests/scenario_stock_quantity_early_planning.rst b/modules/stock_quantity_early_planning/tests/scenario_stock_quantity_early_planning.rst
new file mode 100644
index 0000000000..1b933a9ddb
--- /dev/null
+++ b/modules/stock_quantity_early_planning/tests/scenario_stock_quantity_early_planning.rst
@@ -0,0 +1,166 @@
+======================================
+Stock Quantity Early Planning Scenario
+======================================
+
+Imports::
+
+ >>> from decimal import Decimal
+
+ >>> import datetime as dt
+ >>> from dateutil.relativedelta import relativedelta
+
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import (
+ ... create_company, get_company)
+
+ >>> today = dt.date.today()
+ >>> week1 = today + relativedelta(weeks=1)
+ >>> week2 = today + relativedelta(weeks=2)
+ >>> week3 = today + relativedelta(weeks=3)
+ >>> week4 = today + relativedelta(weeks=4)
+
+Activate modules::
+
+ >>> config = activate_modules('stock_quantity_early_planning')
+
+ >>> Company = Model.get('company.company')
+ >>> Location = Model.get('stock.location')
+ >>> Move = Model.get('stock.move')
+ >>> Party = Model.get('party.party')
+ >>> Product = Model.get('product.product')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> ProductUom = Model.get('product.uom')
+ >>> QuantityEarlyPlan = Model.get('stock.quantity.early_plan')
+ >>> ShipmentOut = Model.get('stock.shipment.out')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create parties::
+
+ >>> customer = Party(name="Customer")
+ >>> customer.save()
+
+Create product::
+
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+ >>> template = ProductTemplate()
+ >>> template.name = "Product"
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> product, = template.products
+ >>> product.cost_price = Decimal('5')
+ >>> _ = template.products.new(cost_price=Decimal('5'))
+ >>> template.save()
+ >>> product1, product2 = template.products
+
+Get stock locations::
+
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> input_loc, = Location.find([('code', '=', 'IN')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+
+Plan receiving some products tomorrow and in 2 week::
+
+ >>> def fill(quantity, product, date):
+ ... move = Move()
+ ... move.product = product
+ ... move.quantity = quantity
+ ... move.from_location = supplier_loc
+ ... move.to_location = input_loc
+ ... move.unit_price = product.cost_price
+ ... move.currency = company.currency
+ ... move.planned_date = date
+ ... move.save()
+
+ >>> fill(5, product1, today)
+ >>> fill(10, product1, week2)
+ >>> fill(5, product1, week4)
+ >>> fill(5, product2, week1)
+ >>> fill(5, product2, week2)
+
+Plan to ship some products in 3 weeks::
+
+ >>> shipment_out1 = ShipmentOut()
+ >>> shipment_out1.planned_date = week3
+ >>> shipment_out1.customer = customer
+ >>> move = shipment_out1.outgoing_moves.new()
+ >>> move.product = product1
+ >>> move.quantity = 4
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> move.unit_price = product1.list_price
+ >>> move.currency = company.currency
+ >>> move = shipment_out1.outgoing_moves.new()
+ >>> move.product = product2
+ >>> move.quantity = 6
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> move.unit_price = product2.list_price
+ >>> move.currency = company.currency
+ >>> shipment_out1.save()
+
+ >>> shipment_out2 = ShipmentOut()
+ >>> shipment_out2.planned_date = week3
+ >>> shipment_out2.customer = customer
+ >>> move = shipment_out2.outgoing_moves.new()
+ >>> move.product = product1
+ >>> move.quantity = 8
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> move.unit_price = product1.list_price
+ >>> move.currency = company.currency
+ >>> shipment_out2.save()
+
+ >>> shipment_out3 = ShipmentOut()
+ >>> shipment_out3.planned_date = week4
+ >>> shipment_out3.customer = customer
+ >>> move = shipment_out3.outgoing_moves.new()
+ >>> move.product = product1
+ >>> move.quantity = 4
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> move.unit_price = product1.list_price
+ >>> move.currency = company.currency
+ >>> shipment_out3.save()
+
+ >>> ShipmentOut.click([shipment_out1, shipment_out2, shipment_out3], 'wait')
+
+Generate early planning::
+
+ >>> generate_planning = Wizard('stock.quantity.early_plan.generate')
+ >>> generate_planning.execute('generate')
+
+Check early planning::
+
+ >>> plan1, = QuantityEarlyPlan.find(
+ ... [('origin', '=', str(shipment_out1))])
+ >>> plan1.earlier_date == week2
+ True
+ >>> plan1.earliest_date == today
+ True
+ >>> plan1.earliest_percentage
+ 0.4
+
+ >>> plan2, = QuantityEarlyPlan.find(
+ ... [('origin', '=', str(shipment_out2))])
+ >>> plan2.earlier_date == week2
+ True
+ >>> plan2.earliest_date == week2
+ True
+ >>> plan2.earliest_percentage
+ 1.0
+
+ >>> plan3, = QuantityEarlyPlan.find(
+ ... [('origin', '=', str(shipment_out3))])
+ >>> plan3.earlier_date == week4
+ True
+ >>> plan3.earliest_date == today
+ True
+ >>> plan3.earliest_percentage
+ 0.75
diff --git a/modules/stock_quantity_early_planning/tests/scenario_stock_quantity_early_planning_incoming.rst b/modules/stock_quantity_early_planning/tests/scenario_stock_quantity_early_planning_incoming.rst
new file mode 100644
index 0000000000..a6ee6286b9
--- /dev/null
+++ b/modules/stock_quantity_early_planning/tests/scenario_stock_quantity_early_planning_incoming.rst
@@ -0,0 +1,149 @@
+===============================================
+Stock Quantity Early Planning Incoming Scenario
+===============================================
+
+Imports::
+
+ >>> from decimal import Decimal
+
+ >>> import datetime as dt
+ >>> from dateutil.relativedelta import relativedelta
+
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import (
+ ... create_company, get_company)
+
+ >>> today = dt.date.today()
+ >>> week1 = today + relativedelta(weeks=1)
+ >>> week2 = today + relativedelta(weeks=2)
+ >>> week3 = today + relativedelta(weeks=3)
+
+Activate modules::
+
+ >>> config = activate_modules('stock_quantity_early_planning')
+
+ >>> Company = Model.get('company.company')
+ >>> Location = Model.get('stock.location')
+ >>> Move = Model.get('stock.move')
+ >>> Party = Model.get('party.party')
+ >>> Product = Model.get('product.product')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> ProductUom = Model.get('product.uom')
+ >>> QuantityEarlyPlan = Model.get('stock.quantity.early_plan')
+ >>> ShipmentOut = Model.get('stock.shipment.out')
+ >>> ShipmentInternal = Model.get('stock.shipment.internal')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create parties::
+
+ >>> customer = Party(name="Customer")
+ >>> customer.save()
+
+Create product::
+
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+ >>> template = ProductTemplate()
+ >>> template.name = "Product"
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> product, = template.products
+ >>> product.cost_price = Decimal('5')
+ >>> template.save()
+ >>> product, = template.products
+
+Get stock locations::
+
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+
+Duplicate warehouse::
+
+ >>> warehouse, = Location.find([('type', '=', 'warehouse')])
+ >>> warehouse2, = warehouse.duplicate()
+
+Plan receiving some products in 1 week in second warehouse::
+
+ >>> def fill(quantity, product, date):
+ ... move = Move()
+ ... move.product = product
+ ... move.quantity = quantity
+ ... move.from_location = supplier_loc
+ ... move.to_location = warehouse2.input_location
+ ... move.unit_price = product.cost_price
+ ... move.currency = company.currency
+ ... move.planned_date = date
+ ... move.save()
+
+ >>> fill(5, product, today)
+ >>> fill(15, product, week1)
+
+Request to ship to first warehouse in 2 and 3 weeks::
+
+ >>> shipment_int1 = ShipmentInternal()
+ >>> shipment_int1.planned_date = week2
+ >>> shipment_int1.from_location = warehouse2.storage_location
+ >>> shipment_int1.to_location = warehouse.storage_location
+ >>> move = shipment_int1.moves.new()
+ >>> move.from_location = warehouse2.storage_location
+ >>> move.to_location = warehouse.storage_location
+ >>> move.product = product
+ >>> move.quantity = 10
+ >>> shipment_int1.save()
+ >>> ShipmentInternal.write(
+ ... [shipment_int1.id], {'state': 'request'}, shipment_int1._context)
+
+ >>> shipment_int2 = ShipmentInternal()
+ >>> shipment_int2.planned_date = week2
+ >>> shipment_int2.from_location = warehouse2.storage_location
+ >>> shipment_int2.to_location = warehouse.storage_location
+ >>> move = shipment_int2.moves.new()
+ >>> move.from_location = warehouse2.storage_location
+ >>> move.to_location = warehouse.storage_location
+ >>> move.product = product
+ >>> move.quantity = 5
+ >>> shipment_int2.save()
+ >>> ShipmentInternal.write(
+ ... [shipment_int2.id], {'state': 'request'}, shipment_int2._context)
+
+Plan to ship in 3 weeks::
+
+ >>> shipment_out = ShipmentOut(warehouse=warehouse)
+ >>> shipment_out.planned_date = week3
+ >>> shipment_out.customer = customer
+ >>> move = shipment_out.outgoing_moves.new()
+ >>> move.product = product
+ >>> move.quantity = 7
+ >>> move.from_location = warehouse.output_location
+ >>> move.to_location = customer_loc
+ >>> move.unit_price = product.list_price
+ >>> move.currency = company.currency
+ >>> shipment_out.save()
+ >>> shipment_out.click('wait')
+
+Generate early planning::
+
+ >>> generate_planning = Wizard('stock.quantity.early_plan.generate')
+ >>> generate_planning.execute('generate')
+
+Check early planning::
+
+ >>> plan, = QuantityEarlyPlan.find(
+ ... [('origin', '=', str(shipment_int1))])
+ >>> plan.earlier_date == week1
+ True
+
+ >>> plan, = QuantityEarlyPlan.find(
+ ... [('origin', '=', str(shipment_int2))])
+ >>> plan.earlier_date == today
+ True
+
+ >>> plan, = QuantityEarlyPlan.find(
+ ... [('origin', '=', str(shipment_out))])
+ >>> plan.earlier_date == week1
+ True
diff --git a/modules/stock_quantity_early_planning/tests/test_module.py b/modules/stock_quantity_early_planning/tests/test_module.py
new file mode 100644
index 0000000000..a4da7e7858
--- /dev/null
+++ b/modules/stock_quantity_early_planning/tests/test_module.py
@@ -0,0 +1,14 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.modules.company.tests import CompanyTestMixin
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockQuantityEarlyPlanningTestCase(CompanyTestMixin, ModuleTestCase):
+ 'Test Stock Quantity Early Planning module'
+ module = 'stock_quantity_early_planning'
+ extras = ['production']
+
+
+del ModuleTestCase
diff --git a/modules/stock_quantity_early_planning/tests/test_scenario.py b/modules/stock_quantity_early_planning/tests/test_scenario.py
new file mode 100644
index 0000000000..dc1d23e7e5
--- /dev/null
+++ b/modules/stock_quantity_early_planning/tests/test_scenario.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import load_doc_tests
+
+
+def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_quantity_early_planning/tox.ini b/modules/stock_quantity_early_planning/tox.ini
new file mode 100644
index 0000000000..c3a8c6c5a6
--- /dev/null
+++ b/modules/stock_quantity_early_planning/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_quantity_early_planning/* -m unittest discover -s tests
+ coverage report --include=./**/stock_quantity_early_planning/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_quantity_early_planning/tryton.cfg b/modules/stock_quantity_early_planning/tryton.cfg
new file mode 100644
index 0000000000..5be395d96b
--- /dev/null
+++ b/modules/stock_quantity_early_planning/tryton.cfg
@@ -0,0 +1,10 @@
+[tryton]
+version=6.7.0
+depends:
+ company
+ ir
+ stock
+extras_depend:
+ production
+xml:
+ stock.xml
diff --git a/modules/stock_quantity_early_planning/view/quantity_early_plan_form.xml b/modules/stock_quantity_early_planning/view/quantity_early_plan_form.xml
new file mode 100644
index 0000000000..9c1d15a467
--- /dev/null
+++ b/modules/stock_quantity_early_planning/view/quantity_early_plan_form.xml
@@ -0,0 +1,46 @@
+
+
+
diff --git a/modules/stock_quantity_early_planning/view/quantity_early_plan_generate_start_form.xml b/modules/stock_quantity_early_planning/view/quantity_early_plan_generate_start_form.xml
new file mode 100644
index 0000000000..747c0242b7
--- /dev/null
+++ b/modules/stock_quantity_early_planning/view/quantity_early_plan_generate_start_form.xml
@@ -0,0 +1,8 @@
+
+
+
diff --git a/modules/stock_quantity_early_planning/view/quantity_early_plan_list.xml b/modules/stock_quantity_early_planning/view/quantity_early_plan_list.xml
new file mode 100644
index 0000000000..de8f828967
--- /dev/null
+++ b/modules/stock_quantity_early_planning/view/quantity_early_plan_list.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_quantity_issue/.drone.yml b/modules/stock_quantity_issue/.drone.yml
new file mode 100644
index 0000000000..b45ef267ef
--- /dev/null
+++ b/modules/stock_quantity_issue/.drone.yml
@@ -0,0 +1,78 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+ check_doc:
+ image: ${IMAGE}
+ commands:
+ - pip install sphinx
+ - python -m sphinx -T -E -W -n -b html doc _build/html
+ - python -m sphinx -T -E -W -n -b linkcheck doc _build
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_quantity_issue/.flake8 b/modules/stock_quantity_issue/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_quantity_issue/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_quantity_issue/.isort.cfg b/modules/stock_quantity_issue/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_quantity_issue/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_quantity_issue/CHANGELOG b/modules/stock_quantity_issue/CHANGELOG
new file mode 100644
index 0000000000..cf8205ed96
--- /dev/null
+++ b/modules/stock_quantity_issue/CHANGELOG
@@ -0,0 +1,17 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+--------------------------
+* Initial release
diff --git a/modules/stock_quantity_issue/COPYRIGHT b/modules/stock_quantity_issue/COPYRIGHT
new file mode 100644
index 0000000000..c2ab832cbd
--- /dev/null
+++ b/modules/stock_quantity_issue/COPYRIGHT
@@ -0,0 +1,14 @@
+Copyright (C) 2020-2022 Cédric Krier
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_quantity_issue/LICENSE b/modules/stock_quantity_issue/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_quantity_issue/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_quantity_issue/MANIFEST.in b/modules/stock_quantity_issue/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_quantity_issue/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_quantity_issue/README.rst b/modules/stock_quantity_issue/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_quantity_issue/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_quantity_issue/__init__.py b/modules/stock_quantity_issue/__init__.py
new file mode 100644
index 0000000000..649a2922f6
--- /dev/null
+++ b/modules/stock_quantity_issue/__init__.py
@@ -0,0 +1,23 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+__all__ = ['register']
+
+from . import ir, stock
+
+
+def register():
+ Pool.register(
+ ir.Cron,
+ stock.QuantityIssue,
+ stock.QuantityIssueProduct,
+ stock.QuantityIssueGenerateStart,
+ module='stock_quantity_issue', type_='model')
+ Pool.register(
+ stock.QuantityIssueGenerate,
+ module='stock_quantity_issue', type_='wizard')
+ Pool.register(
+ stock.QuantityIssueProduction,
+ module='stock_quantity_issue', type_='model', depends=['production'])
diff --git a/modules/stock_quantity_issue/doc/conf.py b/modules/stock_quantity_issue/doc/conf.py
new file mode 100644
index 0000000000..8513b72dd2
--- /dev/null
+++ b/modules/stock_quantity_issue/doc/conf.py
@@ -0,0 +1,61 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+modules_url = 'https://docs.tryton.org/projects/modules-{module}/en/{series}/'
+trytond_url = 'https://docs.tryton.org/projects/server/en/{series}/'
+
+
+def get_info():
+ import configparser
+ import os
+ import subprocess
+ import sys
+
+ module_dir = os.path.dirname(os.path.dirname(__file__))
+
+ config = configparser.ConfigParser()
+ config.read_file(open(os.path.join(module_dir, 'tryton.cfg')))
+ info = dict(config.items('tryton'))
+
+ result = subprocess.run(
+ [sys.executable, 'setup.py', '--name'],
+ stdout=subprocess.PIPE, check=True, cwd=module_dir)
+ info['name'] = result.stdout.decode('utf-8').strip()
+
+ result = subprocess.run(
+ [sys.executable, 'setup.py', '--version'],
+ stdout=subprocess.PIPE, check=True, cwd=module_dir)
+ version = result.stdout.decode('utf-8').strip()
+ if 'dev' in version:
+ info['series'] = 'latest'
+ else:
+ info['series'] = '.'.join(version.split('.', 2)[:2])
+
+ for key in {'depends', 'extras_depend'}:
+ info[key] = info.get(key, '').strip().splitlines()
+ info['modules'] = set(info['depends'] + info['extras_depend'])
+ info['modules'] -= {'ir', 'res'}
+
+ return info
+
+
+info = get_info()
+
+master_doc = 'index'
+project = info['name']
+release = version = info['series']
+default_role = 'ref'
+highlight_language = 'none'
+extensions = [
+ 'sphinx.ext.intersphinx',
+ ]
+intersphinx_mapping = {
+ 'trytond': (trytond_url.format(series=version), None),
+ }
+intersphinx_mapping.update({
+ m: (modules_url.format(
+ module=m.replace('_', '-'), series=version), None)
+ for m in info['modules']
+ })
+
+del get_info, info, modules_url, trytond_url
diff --git a/modules/stock_quantity_issue/doc/design.rst b/modules/stock_quantity_issue/doc/design.rst
new file mode 100644
index 0000000000..b5a5fa4032
--- /dev/null
+++ b/modules/stock_quantity_issue/doc/design.rst
@@ -0,0 +1,51 @@
+******
+Design
+******
+
+The *Stock Quantity Issue Module* introduces the following concepts:
+
+.. _model-stock.quantity.issue:
+
+Stock Quantity Issue
+====================
+
+*Quantity Issues* are generated by a *Scheduled Task*.
+They represent planning issues regarding the quantity of stock available for
+future `Shipments ` or :doc:`Productions
+`.
+
+A best planned date is calculated for each issue.
+Applying this date updates the shipment's, or production's, planned date.
+The issue also lists the `Products ` for which there
+is a quantity issue.
+
+The `Employee ` who processes or solves the
+issue is recorded.
+
+.. seealso::
+
+ Quantity Issues can be found by opening the main menu item:
+
+ |Inventory & Stock --> Quantity Issues|__
+
+ .. |Inventory & Stock --> Quantity Issues| replace:: :menuselection:`Inventory & Stock --> Quantity Issues`
+ __ https://demo.tryton.org/model/stock.quantity.issue
+
+Wizards
+-------
+
+.. _wizard-stock.quantity.issue.generate:
+
+Generate Stock Quantity Issues
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The *Generate Stock Quantity Issues* wizard creates for each warehouse the
+`Stock Quantity Issues ` if there are any.
+When running it deletes any open issues, updates the processing issues with the
+new products and creates new issues.
+
+.. seealso::
+
+ The wizard can be launched by opening:
+
+ :menuselection:`Inventory & Stock --> Quantity Issues --> Generate Stock Quantity Issues`
diff --git a/modules/stock_quantity_issue/doc/index.rst b/modules/stock_quantity_issue/doc/index.rst
new file mode 100644
index 0000000000..f1cc130ab0
--- /dev/null
+++ b/modules/stock_quantity_issue/doc/index.rst
@@ -0,0 +1,13 @@
+###########################
+Stock Quantity Issue Module
+###########################
+
+The *Stock Quantity Issue Module* helps to solve stock quantity issues.
+
+
+.. toctree::
+ :maxdepth: 2
+
+ usage
+ design
+ releases
diff --git a/modules/stock_quantity_issue/doc/releases.rst b/modules/stock_quantity_issue/doc/releases.rst
new file mode 100644
index 0000000000..21b13c4745
--- /dev/null
+++ b/modules/stock_quantity_issue/doc/releases.rst
@@ -0,0 +1,7 @@
+.. _releases-index:
+
+=============
+Release notes
+=============
+
+.. include:: ../CHANGELOG
diff --git a/modules/stock_quantity_issue/doc/usage.rst b/modules/stock_quantity_issue/doc/usage.rst
new file mode 100644
index 0000000000..d5872f89e2
--- /dev/null
+++ b/modules/stock_quantity_issue/doc/usage.rst
@@ -0,0 +1,12 @@
+*****
+Usage
+*****
+
+.. _Generate stock quantity issues:
+
+Generate stock quantity issues
+==============================
+
+You can define a *Scheduled Action* to generate the `Stock Quantity Issues
+` periodically like the `Generate Stock Quantity
+Issues ` wizard does.
diff --git a/modules/stock_quantity_issue/exceptions.py b/modules/stock_quantity_issue/exceptions.py
new file mode 100644
index 0000000000..0e963e4d72
--- /dev/null
+++ b/modules/stock_quantity_issue/exceptions.py
@@ -0,0 +1,7 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.exceptions import UserError
+
+
+class QuantityIssueError(UserError):
+ pass
diff --git a/modules/stock_quantity_issue/ir.py b/modules/stock_quantity_issue/ir.py
new file mode 100644
index 0000000000..f40cad60a3
--- /dev/null
+++ b/modules/stock_quantity_issue/ir.py
@@ -0,0 +1,15 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.pool import PoolMeta
+
+
+class Cron(metaclass=PoolMeta):
+ __name__ = 'ir.cron'
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls.method.selection.extend([
+ ('stock.quantity.issue|generate_issues',
+ "Generate Stock Quantity Issues"),
+ ])
diff --git a/modules/stock_quantity_issue/locale/bg.po b/modules/stock_quantity_issue/locale/bg.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/bg.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/ca.po b/modules/stock_quantity_issue/locale/ca.po
new file mode 100644
index 0000000000..9298076dff
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/ca.po
@@ -0,0 +1,183 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr "Millor data planificada"
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr "Productes amb incidències"
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr "Origen"
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr "Data estimada"
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr "Prioritat"
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr "Processat per"
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr "Productes"
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr "Resolt per"
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr "Estat"
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr "Magatzem"
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr "Magatzems"
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr "Millor data planificada"
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Quantitat prevista"
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr "Incidència"
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr "Producte"
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr "Si es deixa en blanc s'utilitzen tots els magatzems."
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr "La quantitat d’estoc que s’espera que hi hagi al magatzem."
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr "Incidències d'aprovisionament"
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr "Genera incidències d'aprovisionament"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr "Tot"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr "Obert"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr "En procés"
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+"No es pot resoldre l'incidència d'aprovisionament \"%(issue)s\" perquè el "
+"producte \"%(product)s\" encara té una previsió negativa."
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr "Aplica la millor data prevista"
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr "Restebleix a obert"
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr "Processa"
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr "Resoldre"
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr "Usuari a les empreses"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr "Incidències d'aprovisionament"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr "Genera incidències d'aprovisionament"
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr "Incidències d'aprovisionament"
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr "Incidències d'aprovisionament"
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr "Productes amb incidències d'aprovisionament"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr "Genera incidències d'aprovisionament"
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr "Obert"
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr "En procés"
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr "Resolt"
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr "Genera incidencies d'aprovisionament?"
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr "Aplica"
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr "Informació addicional"
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr "Cancel·la"
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr "Genera"
diff --git a/modules/stock_quantity_issue/locale/cs.po b/modules/stock_quantity_issue/locale/cs.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/cs.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/de.po b/modules/stock_quantity_issue/locale/de.po
new file mode 100644
index 0000000000..37222665b4
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/de.po
@@ -0,0 +1,184 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr "Optimales Geplantes Datum"
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr "Unternehmen"
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr "Problemartikel"
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr "Herkunft"
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr "Geplantes Datum"
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr "Priorität"
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr "Bearbeitet von"
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr "Artikel"
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr "Behoben von"
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr "Status"
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr "Logistikstandort"
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr "Logistikstandorte"
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr "Optimales Geplantes Datum"
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Voraussichtliche Menge"
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr "Problem"
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr "Artikel"
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr "Leer lassen, um alle Logistikstandorte zu verwenden."
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr "Der erwartete Lagerbestand für den Logistikstandort."
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr "Verfügbarkeitsprobleme"
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr "Verfügbarkeitsprobleme Ermitteln"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr "Alle"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr "Offen"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr "In Ausführung"
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+"Das Verfügbarkeitsproblem \"%(issue)s\" kann nicht gelöst werden, weil "
+"Artikel \"%(product)s\" immer noch einen negativen voraussichtlichen "
+"Lagerbestand hat."
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr "Optimales Geplantes Datum verwenden"
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr "Zurücksetzen"
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr "Ausführen"
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr "Beheben"
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr "Benutzer im Unternehmen"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr "Verfügbarkeitsprobleme"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr "Verfügbarkeitsprobleme Ermitteln"
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr "Lager Verfügbarkeitsprobleme"
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr "Lager Verfügbarkeitsprobleme Ermitteln"
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr "Lager Verfügbarkeitsprobleme Artikel"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr "Verfügbarkeitsprobleme Ermitteln"
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr "Offen"
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr "In Ausführung"
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr "Behoben"
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr "Verfügbarkeitsprobleme ermitteln?"
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr "Anwenden"
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr "Sonstiges"
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr "Abbrechen"
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr "Ermitteln"
diff --git a/modules/stock_quantity_issue/locale/es.po b/modules/stock_quantity_issue/locale/es.po
new file mode 100644
index 0000000000..04adab6e4c
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/es.po
@@ -0,0 +1,183 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr "Mejor fecha planificada"
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr "Productos con incidencias"
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr "Origen"
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr "Fecha estimada"
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr "Prioridad"
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr "Procesado por"
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr "Productos"
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr "Resuelto por"
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr "Estado"
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr "Almacén"
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr "Almacenes"
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr "Mejor fecha planificada"
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Cantidad prevista"
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr "Incidencia"
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr "Producto"
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr "Si está vacío se utilizan todos los almacenes."
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr "La cantidad de stock que se espera que haya en el almacén."
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr "Incidencias de abastecimiento"
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr "Generar incidencias de abastecimiento"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr "Todo"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr "Abierto"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr "En proceso"
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+"No se puede resolver la incidencia de abastecimiento \"%(issue)s\" porqué el"
+" producto \"%(product)s\" todavía tiene una previsión negativa."
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr "Aplicar la mejor fecha planificada"
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr "Restablecer a Abierto"
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr "Procesar"
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr "Resolver"
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr "Usuario en las empresas"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr "Incidencias de abastecimiento"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr "Generar incidencias de abastecimiento"
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr "Incidencias de abastecimiento"
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr "Generar incidencias de abastecimiento"
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr "Productos con oncidencias de abastecimiento"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr "Generar incidencias de abastecimiento"
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr "Abierto"
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr "En proceso"
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr "Resuelto"
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr "¿Generar incidencias de abastecimiento?"
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr "Aplicar"
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr "Información adicional"
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr "Generar"
diff --git a/modules/stock_quantity_issue/locale/es_419.po b/modules/stock_quantity_issue/locale/es_419.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/es_419.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/et.po b/modules/stock_quantity_issue/locale/et.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/et.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/fa.po b/modules/stock_quantity_issue/locale/fa.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/fa.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/fi.po b/modules/stock_quantity_issue/locale/fi.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/fi.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/fr.po b/modules/stock_quantity_issue/locale/fr.po
new file mode 100644
index 0000000000..9bf0353775
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/fr.po
@@ -0,0 +1,183 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr "Meilleure date planifiée"
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr "Société"
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr "Produits problématiques"
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr "Origine"
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr "Date planifiée"
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr "Priorité"
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr "Traité par"
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr "Produits"
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr "Résolu par"
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr "État"
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr "Entrepôt"
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr "Entrepôts"
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr "Meilleure date planifiée"
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Quantité prévisionnelle"
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr "Problème"
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr "Produit"
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr "Si vide, tous les entrepôts sont utilisés."
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr "La quantité de stock attendue dans l'entrepôt."
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr "Problèmes de quantité"
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr "Générer les problèmes de quantité de stock"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr "Tous"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr "Ouverts"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr "En traitement"
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+"Vous ne pouvez pas résoudre le problème de quantité de stock « %(issue)s » "
+"car le produit « %(product)s » a toujours un prévisionnel négatif."
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr "Appliquer la meilleure date planifiée"
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr "Réinitialiser pour ouvrir"
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr "Traiter"
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr "Résoudre"
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr "Utilisateur dans les sociétés"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr "Problèmes de quantité"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr "Générer les problèmes de quantité de stock"
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr "Problème de quantité de stock"
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr "Générer les problèmes de quantité de stock"
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr "Produit de problème de quantité de stock"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr "Générer les problèmes de quantité de stock"
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr "Ouvert"
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr "En traitement"
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr "Résolu"
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr "Générer les problèmes de quantité de stock ?"
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr "Appliquer"
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr "Autre information"
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr "Annuler"
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr "Générer"
diff --git a/modules/stock_quantity_issue/locale/hu.po b/modules/stock_quantity_issue/locale/hu.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/hu.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/id.po b/modules/stock_quantity_issue/locale/id.po
new file mode 100644
index 0000000000..e974c7ff29
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/id.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr "Perusahaan"
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr "Asal"
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr "Gudang"
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr "Produk"
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr "Proses"
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr "Info Lain"
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr "Batal"
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/it.po b/modules/stock_quantity_issue/locale/it.po
new file mode 100644
index 0000000000..16bf948669
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/it.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr "Origine"
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr "Magazzino"
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr "Magazzini"
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/lo.po b/modules/stock_quantity_issue/locale/lo.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/lo.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/lt.po b/modules/stock_quantity_issue/locale/lt.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/lt.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/nl.po b/modules/stock_quantity_issue/locale/nl.po
new file mode 100644
index 0000000000..138946effc
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/nl.po
@@ -0,0 +1,184 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr "Optimale geplande datum"
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr "Bedrijf"
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr "Probleemartikel"
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr "Oorsprong(herkomst)"
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr "Geplande datum"
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr "Prioriteit"
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr "Verwerkt door"
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr "Producten"
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr "Opgelost door"
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr "Status"
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr "Magazijn"
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr "Magazijnen"
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr "Optimale geplande datum"
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr "Verwachte hoeveelheid"
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr "Probleem"
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr "Product"
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr "Indien leeg worden alle magazijnen gebruikt."
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+"De hoeveelheid voorraad die naar verwachting in het magazijn zal zijn."
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr "Kwantiteitsproblemen"
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr "Problemen met voorraadhoeveelheid genereren"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr "Alle"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr "Open"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr "Verwerken"
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+"U kunt het probleem met de voorraadhoeveelheid \"%(issue)s\" niet oplossen "
+"omdat het product \"%(product)s\" nog steeds een negatieve prognose heeft."
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr "Beste geplande datum toepassen"
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr "Resetten om te openen"
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr "Uitvoeren"
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr "Oplossen"
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr "Gebruiker in het bedrijf"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr "Kwantiteitsproblemen"
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr "Problemen met voorraadhoeveelheid genereren"
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr "Problemen met voorraadbeschikbaarheid"
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr "Identificeer problemen met de beschikbaarheid van magazijnen"
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr "Problemen met voorraadbeschikbaarheid product"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr "Problemen met voorraadhoeveelheid genereren"
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr "Open"
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr "Verwerken"
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr "Opgelost"
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr "Problemen met voorraadhoeveelheid genereren?"
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr "Toepassen"
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr "Overige informatie"
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr "Annuleer"
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr "Genereer"
diff --git a/modules/stock_quantity_issue/locale/pl.po b/modules/stock_quantity_issue/locale/pl.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/pl.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/pt.po b/modules/stock_quantity_issue/locale/pt.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/pt.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/ro.po b/modules/stock_quantity_issue/locale/ro.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/ro.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/ru.po b/modules/stock_quantity_issue/locale/ru.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/ru.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/sl.po b/modules/stock_quantity_issue/locale/sl.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/sl.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/tr.po b/modules/stock_quantity_issue/locale/tr.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/tr.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/uk.po b/modules/stock_quantity_issue/locale/uk.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/uk.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/locale/zh_CN.po b/modules/stock_quantity_issue/locale/zh_CN.po
new file mode 100644
index 0000000000..9aea1e6ea6
--- /dev/null
+++ b/modules/stock_quantity_issue/locale/zh_CN.po
@@ -0,0 +1,181 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.quantity.issue,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,issue_products:"
+msgid "Issue Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,planned_date:"
+msgid "Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,priority:"
+msgid "Priority"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,processed_by:"
+msgid "Processed by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,solved_by:"
+msgid "Solved by"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,state:"
+msgid "State"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.generate.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,best_planned_date:"
+msgid "Best Planned Date"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,forecast_quantity:"
+msgid "Forecast Quantity"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,issue:"
+msgid "Issue"
+msgstr ""
+
+msgctxt "field:stock.quantity.issue.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.generate.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "help:stock.quantity.issue.product,forecast_quantity:"
+msgid "The amount of stock expected to be in the warehouse."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_quantity_issue_form_domain_processing"
+msgid "Processing"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_issue_solve_product_forecast_quantity"
+msgid ""
+"You cannot solve the stock quantity issue \"%(issue)s\" because product "
+"\"%(product)s\" has still a negative forecast."
+msgstr ""
+
+msgctxt ""
+"model:ir.model.button,string:quantity_issue_apply_best_planned_date_button"
+msgid "Apply Best Planned Date"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_open_button"
+msgid "Reset to Open"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_process_button"
+msgid "Process"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:quantity_issue_solve_button"
+msgid "Solve"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_quantity_issue_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_form"
+msgid "Quantity Issues"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_quantity_issue_generate"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue,name:"
+msgid "Stock Quantity Issue"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.generate.start,name:"
+msgid "Stock Quantity Issue Generate"
+msgstr ""
+
+msgctxt "model:stock.quantity.issue.product,name:"
+msgid "Stock Quantity Issue Product"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Generate Stock Quantity Issues"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Open"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Processing"
+msgstr ""
+
+msgctxt "selection:stock.quantity.issue,state:"
+msgid "Solved"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue.generate.start:"
+msgid "Generate Stock Quantity Issues?"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Apply"
+msgstr ""
+
+msgctxt "view:stock.quantity.issue:"
+msgid "Other Info"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.quantity.issue.generate,start,generate:"
+msgid "Generate"
+msgstr ""
diff --git a/modules/stock_quantity_issue/message.xml b/modules/stock_quantity_issue/message.xml
new file mode 100644
index 0000000000..aca594f1ad
--- /dev/null
+++ b/modules/stock_quantity_issue/message.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+ You cannot solve the stock quantity issue "%(issue)s" because product "%(product)s" has still a negative forecast.
+
+
+
diff --git a/modules/stock_quantity_issue/product.xml b/modules/stock_quantity_issue/product.xml
new file mode 100644
index 0000000000..8216d09597
--- /dev/null
+++ b/modules/stock_quantity_issue/product.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+ product.product
+ tree
+
+ product_list
+
+
+
diff --git a/modules/stock_quantity_issue/setup.py b/modules/stock_quantity_issue/setup.py
new file mode 100755
index 0000000000..e0940af9f3
--- /dev/null
+++ b/modules/stock_quantity_issue/setup.py
@@ -0,0 +1,160 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ content = io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+ content = re.sub(
+ r'(?m)^\.\. toctree::\r?\n((^$|^\s.*$)\r?\n)*', '', content)
+ return content
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_quantity_issue'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = []
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [
+ 'python-dateutil',
+ get_require_version('proteus'),
+ get_require_version('trytond_production'),
+ ]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module to manage quantity issue with stock',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": (
+ 'https://docs.tryton.org/projects/modules-stock-quantity-issue/'),
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_quantity_issue',
+ },
+ keywords='tryton stock quantity issue shipment production',
+ package_dir={'trytond.modules.stock_quantity_issue': '.'},
+ packages=(
+ ['trytond.modules.stock_quantity_issue']
+ + ['trytond.modules.stock_quantity_issue.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_quantity_issue': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'Intended Audience :: Manufacturing',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_quantity_issue = trytond.modules.stock_quantity_issue
+ """, # noqa: E501
+ )
diff --git a/modules/stock_quantity_issue/stock.py b/modules/stock_quantity_issue/stock.py
new file mode 100644
index 0000000000..889d530e10
--- /dev/null
+++ b/modules/stock_quantity_issue/stock.py
@@ -0,0 +1,427 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from collections import defaultdict
+from itertools import groupby
+
+from trytond.i18n import gettext
+from trytond.model import (
+ Index, Model, ModelSQL, ModelView, Workflow, fields, sequence_ordered)
+from trytond.modules.company.model import (
+ employee_field, reset_employee, set_employee)
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Eval
+from trytond.transaction import Transaction
+from trytond.wizard import Button, StateAction, StateView, Wizard
+
+from .exceptions import QuantityIssueError
+
+
+class QuantityIssue(
+ sequence_ordered('priority', "Priority", "ASC NULLS LAST"),
+ Workflow, ModelSQL, ModelView):
+ "Stock Quantity Issue"
+ __name__ = 'stock.quantity.issue'
+
+ company = fields.Many2One(
+ 'company.company', "Company", required=True)
+ origin = fields.Reference(
+ "Origin", 'get_origins', required=True,
+ domain={
+ 'stock.shipment.out': [
+ ('company', '=', Eval('company', -1)),
+ ],
+ 'stock.shipment.in.return': [
+ ('company', '=', Eval('company', -1)),
+ ],
+ 'stock.shipment.internal': [
+ ('company', '=', Eval('company', -1)),
+ ],
+ })
+ planned_date = fields.Function(
+ fields.Date("Planned Date"),
+ 'on_change_with_planned_date')
+ best_planned_date = fields.Function(
+ fields.Date("Best Planned Date"),
+ 'get_best_planned_date')
+ warehouse = fields.Function(
+ fields.Many2One('stock.location', "Warehouse"),
+ 'on_change_with_warehouse')
+
+ issue_products = fields.One2Many(
+ 'stock.quantity.issue.product', 'issue', "Issue Products",
+ readonly=True)
+ products = fields.Many2Many(
+ 'stock.quantity.issue.product', 'issue', 'product', "Products",
+ readonly=True,
+ context={
+ 'company': Eval('company'),
+ 'locations': [Eval('warehouse')],
+ 'stock_skip_warehouse': False,
+ 'stock_date_end': Eval('planned_date'),
+ },
+ depends={'company', 'warehouse', 'planned_date'})
+
+ processed_by = employee_field("Processed by", states=['processing'])
+ solved_by = employee_field("Solved by", states=['solved'])
+
+ state = fields.Selection([
+ ('open', "Open"),
+ ('processing', "Processing"),
+ ('solved', "Solved"),
+ ], "State", required=True, readonly=True, sort=False)
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ t = cls.__table__()
+ cls._sql_indexes.add(
+ Index(
+ t, (t.state, Index.Equality()),
+ where=t.state.in_(['open', 'processing'])))
+ cls.priority.readonly = True
+ cls._transitions |= {
+ ('open', 'processing'),
+ ('processing', 'solved'),
+ ('processing', 'open'),
+ }
+ cls._buttons.update({
+ 'open': {
+ 'invisible': Eval('state') != 'processing',
+ 'depends': ['state'],
+ },
+ 'process': {
+ 'invisible': Eval('state') != 'open',
+ 'depends': ['state'],
+ },
+ 'apply_best_planned_date': {
+ 'invisible': Eval('state') != 'processing',
+ 'readonly': ~Eval('best_planned_date'),
+ 'depends': ['state', 'best_planned_date'],
+ },
+ 'solve': {
+ 'invisible': Eval('state') != 'processing',
+ 'depends': ['state'],
+ },
+ })
+
+ @classmethod
+ def default_company(cls):
+ return Transaction().context.get('company')
+
+ @classmethod
+ def get_origins(cls):
+ pool = Pool()
+ Model = pool.get('ir.model')
+ get_name = Model.get_name
+ models = cls._get_origins()
+ return [(m, get_name(m)) for m in models]
+
+ @classmethod
+ def _get_origins(cls):
+ "Return a list of Model names for origin Reference"
+ return [
+ 'stock.shipment.out',
+ 'stock.shipment.in.return',
+ 'stock.shipment.internal',
+ ]
+
+ @fields.depends('origin')
+ def on_change_with_planned_date(self, name=None):
+ if (isinstance(self.origin, Model)
+ and self.origin.id >= 0
+ and hasattr(self.origin, 'planned_date')):
+ return self.origin.planned_date
+
+ def get_best_planned_date(self, name):
+ return max(
+ (p.best_planned_date for p in self.issue_products
+ if p.best_planned_date), default=None)
+
+ @classmethod
+ def default_warehouse(cls):
+ pool = Pool()
+ Location = pool.get('stock.location')
+ return Location.get_default_warehouse()
+
+ @fields.depends('origin')
+ def on_change_with_warehouse(self, name=None):
+ if (isinstance(self.origin, Model) and self.origin.id >= 0
+ and getattr(self.origin, 'warehouse', None)):
+ return self.origin.warehouse.id
+
+ @classmethod
+ def default_state(cls):
+ return 'open'
+
+ def get_rec_name(self, name):
+ return (self.origin.rec_name if isinstance(self.origin, Model)
+ else '(%s)' % self.id)
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('open')
+ @reset_employee('processed_by')
+ def open(cls, issues):
+ pass
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('processing')
+ @set_employee('processed_by')
+ def process(cls, issues):
+ pass
+
+ @classmethod
+ @ModelView.button
+ def apply_best_planned_date(cls, issues):
+ origins = defaultdict(list)
+ for issue in issues:
+ origin = issue.origin
+ if hasattr(origin, 'planned_date'):
+ origins[origin.__class__].append(origin)
+ origin.planned_date = issue.best_planned_date
+ for klass, records in origins.items():
+ klass.save(records)
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('solved')
+ @set_employee('solved_by')
+ def solve(cls, issues):
+ for issue in issues:
+ for product in issue.products:
+ if product.forecast_quantity < 0:
+ raise QuantityIssueError(
+ gettext('stock_quantity_issue.'
+ 'msg_issue_solve_product_forecast_quantity',
+ issue=issue.rec_name,
+ product=product.rec_name))
+
+ @classmethod
+ def generate_issues(cls, warehouses=None, company=None):
+ """
+ For each product check each stock forecast quantity and for each
+ negative day, it creates an issue for each origin on that day.
+
+ If warehouses is specified it checks the stock only for them.
+ """
+ pool = Pool()
+ Date = pool.get('ir.date')
+ Location = pool.get('stock.location')
+ Move = pool.get('stock.move')
+ Product = pool.get('product.product')
+ ProductQuantitiesByWarehouse = pool.get(
+ 'stock.product_quantities_warehouse')
+ User = pool.get('res.user')
+
+ transaction = Transaction()
+ today = Date.today()
+ if warehouses is None:
+ warehouses = Location.search([
+ ('type', '=', 'warehouse'),
+ ])
+ if company is None:
+ company = User(Transaction().user).company
+
+ # Do not keep former open issues as they may no more be valid
+ opens = cls.search([
+ ('company', '=', company.id),
+ ('state', '=', 'open'),
+ ])
+ opens = [
+ i for i in opens if i.warehouse in warehouses or not i.warehouse]
+ cls.delete(opens)
+
+ issues = {}
+ for issue in cls.search([
+ ('company', '=', company.id),
+ ('state', '=', 'processing'),
+ ]):
+ if issue.warehouse not in warehouses:
+ continue
+ # Remove products from processing issues
+ # as they may no more be valid
+ issue.issue_products = []
+ issues[issue.origin] = issue
+
+ # Order by id to speedup reduce_ids
+ products = Product.search([
+ ('type', 'in', ['goods', 'assets']),
+ ('consumable', '=', False),
+ ],
+ order=[('id', 'ASC')])
+
+ for product in products:
+ for warehouse in warehouses:
+ with transaction.set_context(
+ product=product.id,
+ warehouse=warehouse.id,
+ stock_skip_warehouse=False,
+ ):
+ product_quantities = ProductQuantitiesByWarehouse.search([
+ ('date', '>=', today),
+ ('company', '=', company.id),
+ ])
+ issue_products = []
+ for product_quantity in product_quantities:
+ if product_quantity.quantity < 0:
+ moves = Move.search([
+ ('product', '=', product.id),
+ ('planned_date', '=', product_quantity.date),
+ ('from_location', 'child_of',
+ [warehouse.id], 'parent'),
+ ('to_location', 'not child_of',
+ [warehouse.id], 'parent'),
+ ('company', '=', company.id),
+ ])
+ for move in moves:
+ issue_products.append(cls._add(move, issues))
+ else:
+ for issue_product in issue_products:
+ issue_product.best_planned_date = (
+ product_quantity.date)
+ issue_products.clear()
+ cls.save(issues.values())
+
+ @classmethod
+ def _get_origin(cls, move):
+ if move.shipment and move.shipment.__name__ in cls._get_origins():
+ return move.shipment
+
+ @classmethod
+ def _add(cls, move, issues):
+ pool = Pool()
+ Date = pool.get('ir.date')
+ IssueProduct = pool.get('stock.quantity.issue.product')
+
+ origin = cls._get_origin(move)
+
+ if origin in issues:
+ issue = issues[origin]
+ else:
+ issue = issues[origin] = cls(
+ company=origin.company,
+ origin=origin)
+ issue_products = list(getattr(issue, 'issue_products', []))
+ issue_product = IssueProduct.get_from_move(move)
+ issue_products.append(issue_product)
+ issue.issue_products = issue_products
+ planned_date = issue.on_change_with_planned_date()
+ if planned_date:
+ issue.priority = (planned_date - Date.today()).days
+ else:
+ issue.priority = None
+ return issue_product
+
+ @classmethod
+ def copy(cls, issues, default=None):
+ if default is None:
+ default = {}
+ else:
+ default = default.copy()
+ default.setdefault('processed_by')
+ default.setdefault('solved_by')
+ return super().copy(issues, default=default)
+
+
+class QuantityIssueProduction(metaclass=PoolMeta):
+ __name__ = 'stock.quantity.issue'
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls.origin.domain['production'] = [
+ ('company', '=', Eval('company', -1)),
+ ]
+
+ @classmethod
+ def _get_origins(cls):
+ return super()._get_origins() + ['production']
+
+ @classmethod
+ def _get_origin(cls, move):
+ origin = super()._get_origin(move)
+ if not origin:
+ origin = move.production_input
+ return origin
+
+
+class QuantityIssueProduct(ModelSQL):
+ "Stock Quantity Issue Product"
+ __name__ = 'stock.quantity.issue.product'
+
+ issue = fields.Many2One(
+ 'stock.quantity.issue', "Issue",
+ required=True, ondelete='CASCADE')
+ product = fields.Many2One(
+ 'product.product', "Product",
+ required=True, ondelete='CASCADE',
+ domain=[
+ ('type', '!=', 'service'),
+ ])
+ best_planned_date = fields.Date("Best Planned Date")
+ forecast_quantity = fields.Function(
+ fields.Float(
+ "Forecast Quantity",
+ help="The amount of stock expected to be in the warehouse."),
+ 'get_forecast_quantity')
+
+ @classmethod
+ def get_forecast_quantity(cls, records):
+ quantities = {}
+
+ def key(record):
+ return record.warehouse, record.issue.planned_date
+ items = cls.browse(sorted(records, key=key))
+ for (warehouse, date), items in groupby(items, key=key):
+ with Transaction().set_context(
+ location=[warehouse.id],
+ stock_skip_warehouse=True,
+ stock_start_end=date):
+ for item in cls.browse(items):
+ quantities[item.id] = item.product.forecast_quantity
+ return quantities
+
+ def get_rec_name(self, name):
+ return self.product.rec_name
+
+ @classmethod
+ def get_from_move(cls, move):
+ return cls(product=move.product)
+
+
+class QuantityIssueGenerate(Wizard):
+ "Stock Quantity Issue Generate"
+ __name__ = 'stock.quantity.issue.generate'
+ start = StateView(
+ 'stock.quantity.issue.generate.start',
+ 'stock_quantity_issue.quantity_issue_generate_start_view_form', [
+ Button("Cancel", 'end', 'tryton-cancel'),
+ Button("Generate", 'generate', 'tryton-ok', default=True),
+ ])
+ generate = StateAction('stock_quantity_issue.act_quantity_issue_form')
+
+ def transition_generate(self):
+ pool = Pool()
+ QuantityIssue = pool.get('stock.quantity.issue')
+ QuantityIssue.generate_issues(warehouses=self.start.warehouses or None)
+ return 'end'
+
+
+class QuantityIssueGenerateStart(ModelView):
+ "Stock Quantity Issue Generate"
+ __name__ = 'stock.quantity.issue.generate.start'
+ warehouses = fields.Many2Many(
+ 'stock.location', None, None, "Warehouses",
+ domain=[
+ ('type', '=', 'warehouse'),
+ ],
+ help="If empty all warehouses are used.")
+
+ @classmethod
+ def default_warehouses(cls):
+ pool = Pool()
+ Location = pool.get('stock.location')
+ warehouse = Location.get_default_warehouse()
+ if warehouse:
+ return [warehouse]
diff --git a/modules/stock_quantity_issue/stock.xml b/modules/stock_quantity_issue/stock.xml
new file mode 100644
index 0000000000..7567447c66
--- /dev/null
+++ b/modules/stock_quantity_issue/stock.xml
@@ -0,0 +1,136 @@
+
+
+
+
+
+ stock.quantity.issue
+ form
+ quantity_issue_form
+
+
+
+ stock.quantity.issue
+ tree
+ quantity_issue_list
+
+
+
+ Quantity Issues
+ stock.quantity.issue
+
+
+
+
+
+
+
+
+
+
+
+
+ Open
+
+
+
+
+
+
+ Processing
+
+
+
+
+
+
+ All
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ User in companies
+
+
+
+
+
+
+
+
+
+ open
+ Reset to Open
+
+
+
+
+ process
+ Process
+
+
+
+
+ apply_best_planned_date
+ Apply Best Planned Date
+
+
+
+
+ solve
+ Solve
+
+
+
+
+ Generate Stock Quantity Issues
+ stock.quantity.issue.generate
+
+
+
+
+
+
+
+
+
+
+
+
+
+ stock.quantity.issue.generate.start
+ form
+ quantity_issue_generate_start_form
+
+
+
diff --git a/modules/stock_quantity_issue/tests/__init__.py b/modules/stock_quantity_issue/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_quantity_issue/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_quantity_issue/tests/scenario_stock_quantity_issue.rst b/modules/stock_quantity_issue/tests/scenario_stock_quantity_issue.rst
new file mode 100644
index 0000000000..1952e4edf7
--- /dev/null
+++ b/modules/stock_quantity_issue/tests/scenario_stock_quantity_issue.rst
@@ -0,0 +1,153 @@
+=============================
+Stock Quantity Issue Scenario
+=============================
+
+Imports::
+
+ >>> from decimal import Decimal
+
+ >>> import datetime as dt
+ >>> from dateutil.relativedelta import relativedelta
+
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import (
+ ... create_company, get_company)
+
+ >>> today = dt.date.today()
+ >>> week1 = today + relativedelta(weeks=1)
+ >>> week2 = today + relativedelta(weeks=2)
+ >>> week3 = today + relativedelta(weeks=3)
+
+Activate modules::
+
+ >>> config = activate_modules('stock_quantity_issue')
+
+ >>> Company = Model.get('company.company')
+ >>> Cron = Model.get('ir.cron')
+ >>> Location = Model.get('stock.location')
+ >>> Move = Model.get('stock.move')
+ >>> Party = Model.get('party.party')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> ProductUom = Model.get('product.uom')
+ >>> QuantityIssue = Model.get('stock.quantity.issue')
+ >>> ShipmentOut = Model.get('stock.shipment.out')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create parties::
+
+ >>> customer = Party(name="Customer")
+ >>> customer.save()
+
+Create product::
+
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+ >>> template = ProductTemplate()
+ >>> template.name = "Product"
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template.save()
+ >>> product, = template.products
+
+Get stock locations::
+
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> input_loc, = Location.find([('code', '=', 'IN')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+
+Plan receiving some products tomorrow and in 2 week::
+
+ >>> move = Move()
+ >>> move.product = product
+ >>> move.quantity = 6
+ >>> move.from_location = supplier_loc
+ >>> move.to_location = input_loc
+ >>> move.unit_price = Decimal('5')
+ >>> move.currency = company.currency
+ >>> move.planned_date = today
+ >>> move.save()
+
+ >>> move, = Move.duplicate(
+ ... [move], default={
+ ... 'quantity': 14,
+ ... 'planned_date': week2,
+ ... })
+
+Plan to ship some products in 1 week::
+
+ >>> shipment_out1 = ShipmentOut()
+ >>> shipment_out1.planned_date = week1
+ >>> shipment_out1.customer = customer
+ >>> move = shipment_out1.outgoing_moves.new()
+ >>> move.product = product
+ >>> move.quantity = 6
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> move.unit_price = Decimal('20')
+ >>> move.currency = company.currency
+ >>> shipment_out1.save()
+
+ >>> shipment_out2, = ShipmentOut.duplicate([shipment_out1])
+ >>> shipment_out3, = ShipmentOut.duplicate(
+ ... [shipment_out1], default={'planned_date': week3})
+
+ >>> ShipmentOut.click(
+ ... [shipment_out1, shipment_out2, shipment_out3], 'wait')
+
+Generate quantity issues::
+
+ >>> cron_generate_issues = Cron(method='stock.quantity.issue|generate_issues')
+ >>> cron_generate_issues.interval_number = 1
+ >>> cron_generate_issues.interval_type = 'days'
+ >>> cron_generate_issues.click('run_once')
+
+Check quantity issues::
+
+ >>> issues = QuantityIssue.find([('state', '=', 'open')])
+ >>> len(issues)
+ 2
+ >>> issue1, = [i for i in issues if i.origin == shipment_out1]
+ >>> issue2, = [i for i in issues if i.origin == shipment_out2]
+
+ >>> issue1.priority
+ 7
+ >>> issue2.priority
+ 7
+
+ >>> product, = issue1.products
+ >>> product.quantity, product.forecast_quantity
+ (0.0, -6.0)
+
+ >>> issue1.best_planned_date == week2
+ True
+
+Apply best planned date to first shipment::
+
+ >>> issue1.click('process')
+ >>> issue1.click('solve') #doctest: +IGNORE_EXCEPTION_DETAIL
+ Traceback (most recent call last):
+ ...
+ QuantityIssueError: ...
+
+ >>> issue1.click('apply_best_planned_date')
+ >>> issue1.click('solve')
+
+Second shipment does not need to be updated::
+
+ >>> product, = issue2.products
+ >>> product.quantity, product.forecast_quantity
+ (0.0, 0.0)
+
+Regenerate quantity issues::
+
+ >>> cron_generate_issues.click('run_once')
+
+ >>> issues = QuantityIssue.find([('state', '=', 'open')])
+ >>> len(issues)
+ 0
diff --git a/modules/stock_quantity_issue/tests/test_module.py b/modules/stock_quantity_issue/tests/test_module.py
new file mode 100644
index 0000000000..0b0af8ac5a
--- /dev/null
+++ b/modules/stock_quantity_issue/tests/test_module.py
@@ -0,0 +1,14 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.modules.company.tests import CompanyTestMixin
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockQuantityIssueTestCase(CompanyTestMixin, ModuleTestCase):
+ 'Test Stock Quantity Issue module'
+ module = 'stock_quantity_issue'
+ extras = ['production']
+
+
+del ModuleTestCase
diff --git a/modules/stock_quantity_issue/tests/test_scenario.py b/modules/stock_quantity_issue/tests/test_scenario.py
new file mode 100644
index 0000000000..dc1d23e7e5
--- /dev/null
+++ b/modules/stock_quantity_issue/tests/test_scenario.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import load_doc_tests
+
+
+def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_quantity_issue/tox.ini b/modules/stock_quantity_issue/tox.ini
new file mode 100644
index 0000000000..f0f826d2c0
--- /dev/null
+++ b/modules/stock_quantity_issue/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_quantity_issue/* -m unittest discover -s tests
+ coverage report --include=./**/stock_quantity_issue/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_quantity_issue/tryton.cfg b/modules/stock_quantity_issue/tryton.cfg
new file mode 100644
index 0000000000..43702fa2d3
--- /dev/null
+++ b/modules/stock_quantity_issue/tryton.cfg
@@ -0,0 +1,13 @@
+[tryton]
+version=6.7.0
+depends:
+ company
+ ir
+ product
+ stock
+extras_depend:
+ production
+xml:
+ product.xml
+ stock.xml
+ message.xml
diff --git a/modules/stock_quantity_issue/view/product_list.xml b/modules/stock_quantity_issue/view/product_list.xml
new file mode 100644
index 0000000000..9876e6d4d3
--- /dev/null
+++ b/modules/stock_quantity_issue/view/product_list.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_quantity_issue/view/quantity_issue_form.xml b/modules/stock_quantity_issue/view/quantity_issue_form.xml
new file mode 100644
index 0000000000..2a872d248b
--- /dev/null
+++ b/modules/stock_quantity_issue/view/quantity_issue_form.xml
@@ -0,0 +1,40 @@
+
+
+
diff --git a/modules/stock_quantity_issue/view/quantity_issue_generate_start_form.xml b/modules/stock_quantity_issue/view/quantity_issue_generate_start_form.xml
new file mode 100644
index 0000000000..377c24e7eb
--- /dev/null
+++ b/modules/stock_quantity_issue/view/quantity_issue_generate_start_form.xml
@@ -0,0 +1,8 @@
+
+
+
diff --git a/modules/stock_quantity_issue/view/quantity_issue_list.xml b/modules/stock_quantity_issue/view/quantity_issue_list.xml
new file mode 100644
index 0000000000..d64f3e8196
--- /dev/null
+++ b/modules/stock_quantity_issue/view/quantity_issue_list.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_secondary_unit/.drone.yml b/modules/stock_secondary_unit/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_secondary_unit/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_secondary_unit/.flake8 b/modules/stock_secondary_unit/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_secondary_unit/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_secondary_unit/.isort.cfg b/modules/stock_secondary_unit/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_secondary_unit/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_secondary_unit/CHANGELOG b/modules/stock_secondary_unit/CHANGELOG
new file mode 100644
index 0000000000..84a1234c2f
--- /dev/null
+++ b/modules/stock_secondary_unit/CHANGELOG
@@ -0,0 +1,24 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Initial release
diff --git a/modules/stock_secondary_unit/COPYRIGHT b/modules/stock_secondary_unit/COPYRIGHT
new file mode 100644
index 0000000000..80fddcf697
--- /dev/null
+++ b/modules/stock_secondary_unit/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2019-2022 Cédric Krier
+Copyright (C) 2019-2022 B2CK
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_secondary_unit/LICENSE b/modules/stock_secondary_unit/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_secondary_unit/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_secondary_unit/MANIFEST.in b/modules/stock_secondary_unit/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_secondary_unit/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_secondary_unit/README.rst b/modules/stock_secondary_unit/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_secondary_unit/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_secondary_unit/__init__.py b/modules/stock_secondary_unit/__init__.py
new file mode 100644
index 0000000000..396d2ea91d
--- /dev/null
+++ b/modules/stock_secondary_unit/__init__.py
@@ -0,0 +1,17 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import stock
+
+__all__ = ['register']
+
+
+def register():
+ Pool.register(
+ stock.Move,
+ stock.ShipmentIn,
+ stock.ShipmentOut,
+ stock.ShipmentOutReturn,
+ module='stock_secondary_unit', type_='model')
diff --git a/modules/stock_secondary_unit/doc/index.rst b/modules/stock_secondary_unit/doc/index.rst
new file mode 100644
index 0000000000..bb3a18ad33
--- /dev/null
+++ b/modules/stock_secondary_unit/doc/index.rst
@@ -0,0 +1,5 @@
+Stock Secondary Unit Module
+###########################
+
+The stock secondary unit module adds a secondary unit of measure on the stock
+move.
diff --git a/modules/stock_secondary_unit/locale/bg.po b/modules/stock_secondary_unit/locale/bg.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/bg.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/ca.po b/modules/stock_secondary_unit/locale/ca.po
new file mode 100644
index 0000000000..a45f138c39
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/ca.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr "Categoria de UdM secundaria del producte"
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr "Quantitat secundaria"
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr "Unitat secundaria"
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr "Preu unitari secundari"
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr "Quantitat:"
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr "Preu unitari:"
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr "Unitat:"
diff --git a/modules/stock_secondary_unit/locale/cs.po b/modules/stock_secondary_unit/locale/cs.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/cs.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/de.po b/modules/stock_secondary_unit/locale/de.po
new file mode 100644
index 0000000000..081850ddc5
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/de.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr "Artikel Zweitmaßeinheitenkategorie"
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr "Zweitmenge"
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr "Zweitmaßeinheit"
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr "Zweiteinzelpreis"
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr "Menge:"
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr "Einzelpreis:"
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr "Einheit:"
diff --git a/modules/stock_secondary_unit/locale/es.po b/modules/stock_secondary_unit/locale/es.po
new file mode 100644
index 0000000000..e85ec9e490
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/es.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr "Categoría de UdM secundaria del producto"
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr "Cantidad secundaria"
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr "Unidad secundaria"
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr "Precio unitario secundario"
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr "Cantidad:"
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr "Precio unitario:"
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr "Unidad:"
diff --git a/modules/stock_secondary_unit/locale/es_419.po b/modules/stock_secondary_unit/locale/es_419.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/es_419.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/et.po b/modules/stock_secondary_unit/locale/et.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/et.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/fa.po b/modules/stock_secondary_unit/locale/fa.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/fa.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/fi.po b/modules/stock_secondary_unit/locale/fi.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/fi.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/fr.po b/modules/stock_secondary_unit/locale/fr.po
new file mode 100644
index 0000000000..eecb661f91
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/fr.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr "Catégorie d'UDM secondaire du produit"
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr "Quantité secondaire"
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr "Unité secondaire"
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr "Prix unitaire secondaire"
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr "Quantité :"
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr "Prix unitaire :"
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr "Unité :"
diff --git a/modules/stock_secondary_unit/locale/hu.po b/modules/stock_secondary_unit/locale/hu.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/hu.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/id.po b/modules/stock_secondary_unit/locale/id.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/id.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/it.po b/modules/stock_secondary_unit/locale/it.po
new file mode 100644
index 0000000000..f20aa75502
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/it.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr "Categoria UdM secondaria prodotto"
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr "Quantità secondaria"
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr "Unità secondaria"
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr "Prezzo unitario secondario"
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr "Quantità:"
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr "Prezzo unitario:"
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr "Unità:"
diff --git a/modules/stock_secondary_unit/locale/lo.po b/modules/stock_secondary_unit/locale/lo.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/lo.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/lt.po b/modules/stock_secondary_unit/locale/lt.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/lt.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/nl.po b/modules/stock_secondary_unit/locale/nl.po
new file mode 100644
index 0000000000..08c2a9e1d2
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/nl.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr "Product ondergeschikte maateenheid categorie"
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr "Secundaire hoeveelheid"
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr "Secundaire eenheid"
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr "secundaire eenheidsprijs"
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr "Hoeveelheid:"
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr "Eenheid prijs:"
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr "Eenheid:"
diff --git a/modules/stock_secondary_unit/locale/pl.po b/modules/stock_secondary_unit/locale/pl.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/pl.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/pt.po b/modules/stock_secondary_unit/locale/pt.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/pt.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/ro.po b/modules/stock_secondary_unit/locale/ro.po
new file mode 100644
index 0000000000..ba1d9fafce
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/ro.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr "Preţ Unitate Secundara"
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/ru.po b/modules/stock_secondary_unit/locale/ru.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/ru.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/sl.po b/modules/stock_secondary_unit/locale/sl.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/sl.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/tr.po b/modules/stock_secondary_unit/locale/tr.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/tr.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/uk.po b/modules/stock_secondary_unit/locale/uk.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/uk.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/locale/zh_CN.po b/modules/stock_secondary_unit/locale/zh_CN.po
new file mode 100644
index 0000000000..581b15ca41
--- /dev/null
+++ b/modules/stock_secondary_unit/locale/zh_CN.po
@@ -0,0 +1,31 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move,product_secondary_uom_category:"
+msgid "Product Secondary UOM Category"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_quantity:"
+msgid "Secondary Quantity"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit:"
+msgid "Secondary Unit"
+msgstr ""
+
+msgctxt "field:stock.move,secondary_unit_price:"
+msgid "Secondary Unit Price"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Quantity:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit Price:"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Unit:"
+msgstr ""
diff --git a/modules/stock_secondary_unit/setup.py b/modules/stock_secondary_unit/setup.py
new file mode 100755
index 0000000000..f1f59a741d
--- /dev/null
+++ b/modules/stock_secondary_unit/setup.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_secondary_unit'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = []
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = []
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module to add a secondary unit on stock move',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_secondary_unit',
+ },
+ keywords='tryton stock secondary unit',
+ package_dir={'trytond.modules.stock_secondary_unit': '.'},
+ packages=(
+ ['trytond.modules.stock_secondary_unit']
+ + ['trytond.modules.stock_secondary_unit.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_secondary_unit': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_secondary_unit = trytond.modules.stock_secondary_unit
+ """,
+ )
diff --git a/modules/stock_secondary_unit/stock.py b/modules/stock_secondary_unit/stock.py
new file mode 100644
index 0000000000..d5efb0b8dc
--- /dev/null
+++ b/modules/stock_secondary_unit/stock.py
@@ -0,0 +1,152 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.model import fields
+from trytond.modules.currency.fields import Monetary
+from trytond.modules.product import price_digits, round_price
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Eval
+
+
+class Move(metaclass=PoolMeta):
+ __name__ = 'stock.move'
+
+ secondary_quantity = fields.Function(fields.Float(
+ "Secondary Quantity", digits='secondary_unit',
+ states={
+ 'invisible': ~Eval('secondary_unit'),
+ 'readonly': Eval('state').in_(
+ ['cancelled', 'assigned', 'done']),
+ }),
+ 'on_change_with_secondary_quantity', setter='set_secondary')
+ secondary_unit = fields.Many2One(
+ 'product.uom', "Secondary Unit", ondelete='RESTRICT',
+ domain=[
+ ('category', '=', Eval('product_secondary_uom_category')),
+ ],
+ states={
+ 'invisible': ~Eval('product_secondary_uom_category'),
+ 'readonly': Eval('state').in_(['cancelled', 'assigned', 'done']),
+ })
+ secondary_unit_price = fields.Function(
+ Monetary(
+ "Secondary Unit Price", currency='currency', digits=price_digits,
+ states={
+ 'invisible': (~Eval('unit_price_required')
+ | ~Eval('secondary_unit')),
+ 'readonly': Eval('state') != 'draft',
+ }),
+ 'on_change_with_secondary_unit_price', setter='set_secondary')
+
+ product_secondary_uom_category = fields.Function(
+ fields.Many2One(
+ 'product.uom.category', "Product Secondary UOM Category"),
+ 'get_product_secondary_uom_category')
+
+ @fields.depends('quantity', 'uom', 'secondary_unit', 'origin')
+ def on_change_with_secondary_quantity(self, name=None):
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ if (self.quantity and self.uom and self.secondary_unit
+ and (self.secondary_uom_factor or self.secondary_uom_rate)):
+ return Uom.compute_qty(
+ self.uom, self.quantity,
+ self.secondary_unit, round=True,
+ factor=self.secondary_uom_factor, rate=self.secondary_uom_rate)
+ else:
+ return None
+
+ @fields.depends('secondary_quantity', 'secondary_unit', 'uom', 'origin')
+ def on_change_secondary_quantity(self):
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ if (self.secondary_quantity and self.secondary_unit and self.uom
+ and (self.secondary_uom_factor or self.secondary_uom_rate)):
+ self.quantity = Uom.compute_qty(
+ self.secondary_unit, self.secondary_quantity,
+ self.uom, round=True,
+ factor=self.secondary_uom_rate, rate=self.secondary_uom_factor)
+
+ @fields.depends('unit_price', 'uom', 'secondary_unit', 'origin')
+ def on_change_with_secondary_unit_price(self, name=None):
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ if (self.unit_price and self.uom and self.secondary_unit
+ and (self.secondary_uom_factor or self.secondary_uom_rate)):
+ unit_price = Uom.compute_price(
+ self.uom, self.unit_price, self.secondary_unit,
+ factor=self.secondary_uom_factor, rate=self.secondary_uom_rate
+ )
+ return round_price(unit_price)
+ else:
+ return None
+
+ @fields.depends('secondary_unit_price', 'secondary_unit', 'uom', 'origin')
+ def on_change_secondary_unit_price(self, name=None):
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ if (self.secondary_unit_price and self.secondary_unit and self.uom
+ and (self.secondary_uom_factor or self.secondary_uom_rate)):
+ self.unit_price = Uom.compute_price(
+ self.secondary_unit, self.secondary_unit_price, self.uom,
+ factor=self.secondary_uom_rate, rate=self.secondary_uom_factor)
+ self.unit_price = round_price(self.unit_price)
+
+ @fields.depends(methods=[
+ 'on_change_secondary_quantity', 'on_change_secondary_unit_price'])
+ def on_change_secondary_unit(self):
+ self.on_change_secondary_quantity()
+ self.on_change_secondary_unit_price()
+
+ def get_product_secondary_uom_category(self, name):
+ category = None
+ if self.secondary_unit:
+ # Stay valid even if origin has been deleted
+ category = self.secondary_unit.category.id
+ if isinstance(self.origin, self.__class__) and self.origin != self:
+ if self.origin.product_secondary_uom_category:
+ category = self.origin.product_secondary_uom_category.id
+ return category
+
+ @classmethod
+ def set_secondary(cls, lines, name, value):
+ pass
+
+ @property
+ def secondary_uom_factor(self):
+ if isinstance(self.origin, self.__class__) and self.origin != self:
+ return self.origin.secondary_uom_factor
+
+ @property
+ def secondary_uom_rate(self):
+ if isinstance(self.origin, self.__class__) and self.origin != self:
+ return self.origin.secondary_uom_rate
+
+
+class ShipmentIn(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in'
+
+ def _get_inventory_move(self, incoming_move):
+ move = super()._get_inventory_move(incoming_move)
+ if move:
+ move.secondary_unit = incoming_move.secondary_unit
+ return move
+
+
+class ShipmentOut(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out'
+
+ def _get_inventory_move(self, move):
+ inventory_move = super()._get_inventory_move(move)
+ if inventory_move:
+ inventory_move.secondary_unit = move.secondary_unit
+ return inventory_move
+
+
+class ShipmentOutReturn(metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out.return'
+
+ def _get_inventory_move(self, incoming_move):
+ move = super()._get_inventory_move(incoming_move)
+ if move:
+ move.secondary_unit = incoming_move.secondary_unit
+ return move
diff --git a/modules/stock_secondary_unit/stock.xml b/modules/stock_secondary_unit/stock.xml
new file mode 100644
index 0000000000..8cfe749d82
--- /dev/null
+++ b/modules/stock_secondary_unit/stock.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+ stock.move
+
+ stock_move_form
+
+
+
+ stock.move
+
+ stock_move_tree
+
+
+
+ stock.move
+
+ stock_move_tree
+
+
+
+ stock.move
+
+ stock_move_tree
+
+
+
+ stock.move
+
+ stock_move_tree
+
+
+
diff --git a/modules/stock_secondary_unit/tests/__init__.py b/modules/stock_secondary_unit/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_secondary_unit/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_secondary_unit/tests/test_module.py b/modules/stock_secondary_unit/tests/test_module.py
new file mode 100644
index 0000000000..2179f6b3ac
--- /dev/null
+++ b/modules/stock_secondary_unit/tests/test_module.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockSecondaryUnitTestCase(ModuleTestCase):
+ 'Test Stock Secondary Unit module'
+ module = 'stock_secondary_unit'
+
+
+del ModuleTestCase
diff --git a/modules/stock_secondary_unit/tox.ini b/modules/stock_secondary_unit/tox.ini
new file mode 100644
index 0000000000..809e160d2c
--- /dev/null
+++ b/modules/stock_secondary_unit/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_secondary_unit/* -m unittest discover -s tests
+ coverage report --include=./**/stock_secondary_unit/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_secondary_unit/tryton.cfg b/modules/stock_secondary_unit/tryton.cfg
new file mode 100644
index 0000000000..c6e41cde10
--- /dev/null
+++ b/modules/stock_secondary_unit/tryton.cfg
@@ -0,0 +1,8 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ stock
+ product
+xml:
+ stock.xml
diff --git a/modules/stock_secondary_unit/view/stock_move_form.xml b/modules/stock_secondary_unit/view/stock_move_form.xml
new file mode 100644
index 0000000000..b6717d88bf
--- /dev/null
+++ b/modules/stock_secondary_unit/view/stock_move_form.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_secondary_unit/view/stock_move_tree.xml b/modules/stock_secondary_unit/view/stock_move_tree.xml
new file mode 100644
index 0000000000..da5b2ddfcf
--- /dev/null
+++ b/modules/stock_secondary_unit/view/stock_move_tree.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/stock_shipment_cost/.drone.yml b/modules/stock_shipment_cost/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_shipment_cost/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_shipment_cost/.flake8 b/modules/stock_shipment_cost/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_shipment_cost/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_shipment_cost/.isort.cfg b/modules/stock_shipment_cost/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_shipment_cost/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_shipment_cost/CHANGELOG b/modules/stock_shipment_cost/CHANGELOG
new file mode 100644
index 0000000000..36389c5856
--- /dev/null
+++ b/modules/stock_shipment_cost/CHANGELOG
@@ -0,0 +1,16 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Store cost in carrier currency
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add cost allocation method
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Initial release
diff --git a/modules/stock_shipment_cost/COPYRIGHT b/modules/stock_shipment_cost/COPYRIGHT
new file mode 100644
index 0000000000..d0b4a3655d
--- /dev/null
+++ b/modules/stock_shipment_cost/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2020-2022 B2CK
+Copyright (C) 2020-2022 Cédric Krier
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_shipment_cost/LICENSE b/modules/stock_shipment_cost/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_shipment_cost/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_shipment_cost/MANIFEST.in b/modules/stock_shipment_cost/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_shipment_cost/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_shipment_cost/README.rst b/modules/stock_shipment_cost/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_shipment_cost/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_shipment_cost/__init__.py b/modules/stock_shipment_cost/__init__.py
new file mode 100644
index 0000000000..5b777855f7
--- /dev/null
+++ b/modules/stock_shipment_cost/__init__.py
@@ -0,0 +1,27 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.modules.stock.stock_reporting_margin import Abstract
+from trytond.pool import Pool
+
+from . import carrier, stock, stock_reporting_margin
+from .stock import ShipmentCostMixin
+
+__all__ = ['register', 'ShipmentCostMixin']
+
+
+def register():
+ Pool.register(
+ carrier.Carrier,
+ stock.Move,
+ stock.ShipmentOut,
+ stock.ShipmentOutReturn,
+ stock_reporting_margin.Context,
+ module='stock_shipment_cost', type_='model')
+ Pool.register(
+ module='stock_shipment_cost', type_='wizard')
+ Pool.register(
+ module='stock_shipment_cost', type_='report')
+ Pool.register_mixin(
+ stock_reporting_margin.AbstractShipmentOutCostMixin, Abstract,
+ module='stock_shipment_cost')
diff --git a/modules/stock_shipment_cost/carrier.py b/modules/stock_shipment_cost/carrier.py
new file mode 100644
index 0000000000..113478f103
--- /dev/null
+++ b/modules/stock_shipment_cost/carrier.py
@@ -0,0 +1,18 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.model import fields
+from trytond.pool import PoolMeta
+
+
+class Carrier(metaclass=PoolMeta):
+ __name__ = 'carrier'
+
+ shipment_cost_allocation_method = fields.Selection([
+ ('cost', "By Cost"),
+ ], "Allocation Method", required=True,
+ help="Method to allocate shipment cost.")
+
+ @classmethod
+ def default_shipment_cost_allocation_method(cls):
+ return 'cost'
diff --git a/modules/stock_shipment_cost/carrier.xml b/modules/stock_shipment_cost/carrier.xml
new file mode 100644
index 0000000000..f5bb8a3121
--- /dev/null
+++ b/modules/stock_shipment_cost/carrier.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ carrier
+
+ carrier_form
+
+
+
diff --git a/modules/stock_shipment_cost/doc/index.rst b/modules/stock_shipment_cost/doc/index.rst
new file mode 100644
index 0000000000..c1d9760785
--- /dev/null
+++ b/modules/stock_shipment_cost/doc/index.rst
@@ -0,0 +1,7 @@
+##########################
+Stock Shipment Cost Module
+##########################
+
+The *Stock Shipment Cost Module* adds a shipment cost on the outgoing moves
+which is calculated from the carrier purchase price.
+This cost is added to the product margin reports.
diff --git a/modules/stock_shipment_cost/locale/bg.po b/modules/stock_shipment_cost/locale/bg.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/bg.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/ca.po b/modules/stock_shipment_cost/locale/ca.po
new file mode 100644
index 0000000000..c9a8724c7d
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/ca.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr "Mètode d'assignació"
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr "Preu de cost del enviament"
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr "Inclou cost del enviament"
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr "Transportista"
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr "Cost"
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr "Moneda cost"
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr "Moneda cost"
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr "Edita cost"
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr "Cost"
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr "Cost enviament només lectura"
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr "Transportista"
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr "Cost"
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr "Moneda cost"
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr "Moneda cost"
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr "Edita cost"
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr "Cost"
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr "Cost enviament només lectura"
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr "Mètode per assignar les despeses d'enviament."
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr "Marca per editar el cost."
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr "Marca per editar el cost."
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr "Per cost"
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr "Costos"
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr "Costos"
diff --git a/modules/stock_shipment_cost/locale/cs.po b/modules/stock_shipment_cost/locale/cs.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/cs.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/de.po b/modules/stock_shipment_cost/locale/de.po
new file mode 100644
index 0000000000..b79e220d10
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/de.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr "Zuordnungsmethode"
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr "Lieferkosten Warenausgangslieferung"
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr "Lieferkosten Warenausgangslieferung Berücksichtigen"
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr "Versanddienstleister"
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr "Kosten"
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr "Währung Kosten"
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr "Währung Kosten"
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr "Kosten Bearbeiten"
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr "Kosten"
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr "Lieferkosten Schreibgeschützt"
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr "Versanddienstleister"
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr "Kosten"
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr "Währung Kosten"
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr "Währung Kosten"
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr "Kosten Bearbeiten"
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr "Kosten"
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr "Lieferkosten Schreibgeschützt"
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr "Methode zum Zuordnen von Lieferkosten."
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr "Aktivieren um die Kosten zu bearbeiten."
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr "Aktivieren um die Kosten zu bearbeiten."
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr "Kosten"
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr "Kosten"
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr "Kosten"
diff --git a/modules/stock_shipment_cost/locale/es.po b/modules/stock_shipment_cost/locale/es.po
new file mode 100644
index 0000000000..8d72bf46a6
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/es.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr "Método de asignación"
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr "Precio de coste del envío"
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr "Incluir coste del envío"
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr "Transportista"
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr "Coste"
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr "Moneda coste"
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr "Moneda coste"
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr "Editar coste"
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr "Coste"
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr "Coste envío solo lectura"
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr "Transportista"
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr "Coste"
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr "Moneda coste"
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr "Moneda coste"
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr "Editar coste"
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr "Coste"
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr "Coste envío solo lectura"
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr "Método para asignar los costes de envío."
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr "Marcar para editar el coste."
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr "Marcar para editar el coste."
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr "Por coste"
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr "Costes"
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr "Costes"
diff --git a/modules/stock_shipment_cost/locale/es_419.po b/modules/stock_shipment_cost/locale/es_419.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/es_419.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/et.po b/modules/stock_shipment_cost/locale/et.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/et.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/fa.po b/modules/stock_shipment_cost/locale/fa.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/fa.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/fi.po b/modules/stock_shipment_cost/locale/fi.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/fi.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/fr.po b/modules/stock_shipment_cost/locale/fr.po
new file mode 100644
index 0000000000..43c634f69a
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/fr.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr "Méthode d'allocation"
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr "Prix de revient d'expédition"
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr "Inclure le coût d'expédition"
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr "Transporteur"
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr "Coût"
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr "Devise du coût"
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr "Devise du coût"
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr "Modifier le coût"
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr "Coût"
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr "Coût d'expédition en lecture seule"
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr "Transporteur"
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr "Coût"
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr "Devise du coût"
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr "Devise du coût"
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr "Modifier le coût"
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr "Coût"
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr "Coût d'expédition en lecture seule"
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr "Méthode d'allocation des frais d'expédition."
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr "Cochez pour modifier le coût."
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr "Cochez pour modifier le coût."
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr "Par coût"
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr "Coûts"
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr "Coûts"
diff --git a/modules/stock_shipment_cost/locale/hu.po b/modules/stock_shipment_cost/locale/hu.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/hu.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/id.po b/modules/stock_shipment_cost/locale/id.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/id.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/it.po b/modules/stock_shipment_cost/locale/it.po
new file mode 100644
index 0000000000..0d9f56cbd5
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/it.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr "Metodo di allocazione"
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr "Prezzo di costo di spedizione"
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr "Includi il costo di spedizione"
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr "Vettore"
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr "Costo"
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr "Valuta di costo"
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr "Valuta di costo"
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr "Modifica costo"
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr "Costo"
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr "Costo di spedizione in sola lettura"
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr "Vettore"
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr "Costo"
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr "Valuta di costo"
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr "Valuta di costo"
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr "Modifica costo"
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr "Costo"
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr "Costo di spedizione in sola lettura"
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr "Metodo per allocare il costo di spedizione."
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr "Spunta per modificare il costo."
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr "Spunta per modificare il costo."
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr "Per costo"
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr "Costi"
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr "Costi"
diff --git a/modules/stock_shipment_cost/locale/lo.po b/modules/stock_shipment_cost/locale/lo.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/lo.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/lt.po b/modules/stock_shipment_cost/locale/lt.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/lt.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/nl.po b/modules/stock_shipment_cost/locale/nl.po
new file mode 100644
index 0000000000..3b5fbd55e9
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/nl.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr "Toewijzingsmethode"
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr "Verzendkosten"
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr "Inclusief verzendkosten"
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr "Transporteur"
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr "Kosten"
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr "Kosten Valuta"
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr "Kosten Valuta"
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr "Kosten bewerken"
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr "Kosten"
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr "Verzendkosten Alleen Lezen"
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr "Transporteur"
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr "Kosten"
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr "Kosten Valuta"
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr "Kosten Valuta"
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr "Kosten bewerken"
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr "Kosten"
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr "Verzendkosten Alleen Lezen"
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr "Methode om verzendkosten toe te wijzen."
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr "Vink aan om de kosten te bewerken."
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr "Vink aan om de kosten te bewerken."
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr "Op kosten"
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr "Kosten"
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr "Kosten"
diff --git a/modules/stock_shipment_cost/locale/pl.po b/modules/stock_shipment_cost/locale/pl.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/pl.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/pt.po b/modules/stock_shipment_cost/locale/pt.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/pt.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/ro.po b/modules/stock_shipment_cost/locale/ro.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/ro.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/ru.po b/modules/stock_shipment_cost/locale/ru.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/ru.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/sl.po b/modules/stock_shipment_cost/locale/sl.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/sl.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/tr.po b/modules/stock_shipment_cost/locale/tr.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/tr.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/uk.po b/modules/stock_shipment_cost/locale/uk.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/uk.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/locale/zh_CN.po b/modules/stock_shipment_cost/locale/zh_CN.po
new file mode 100644
index 0000000000..0cce38d5bd
--- /dev/null
+++ b/modules/stock_shipment_cost/locale/zh_CN.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:carrier,shipment_cost_allocation_method:"
+msgid "Allocation Method"
+msgstr ""
+
+msgctxt "field:stock.move,shipment_out_cost_price:"
+msgid "Shipment Cost Price"
+msgstr ""
+
+msgctxt "field:stock.reporting.margin.context,include_shipment_cost:"
+msgid "Include Shipment Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,carrier:"
+msgid "Carrier"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_currency_used:"
+msgid "Cost Currency"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_edit:"
+msgid "Edit Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,cost_used:"
+msgid "Cost"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,shipment_cost_readonly:"
+msgid "Shipment Cost Read Only"
+msgstr ""
+
+msgctxt "help:carrier,shipment_cost_allocation_method:"
+msgid "Method to allocate shipment cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,cost_edit:"
+msgid "Check to edit the cost."
+msgstr ""
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Cost"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Costs"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Costs"
+msgstr ""
diff --git a/modules/stock_shipment_cost/setup.py b/modules/stock_shipment_cost/setup.py
new file mode 100755
index 0000000000..2cfb36c61a
--- /dev/null
+++ b/modules/stock_shipment_cost/setup.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ content = io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+ content = re.sub(
+ r'(?m)^\.\. toctree::\r?\n((^$|^\s.*$)\r?\n)*', '', content)
+ return content
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_shipment_cost'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = ['python-sql']
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [get_require_version('proteus')]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module for stock shipment cost',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": (
+ 'https://docs.tryton.org/projects/modules-stock-shipment-cost/'),
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_shipment_cost',
+ },
+ keywords='tryton stock shipment cost',
+ package_dir={'trytond.modules.stock_shipment_cost': '.'},
+ packages=(
+ ['trytond.modules.stock_shipment_cost']
+ + ['trytond.modules.stock_shipment_cost.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_shipment_cost': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_shipment_cost = trytond.modules.stock_shipment_cost
+ """, # noqa: E501
+ )
diff --git a/modules/stock_shipment_cost/stock.py b/modules/stock_shipment_cost/stock.py
new file mode 100644
index 0000000000..4d4baf5b24
--- /dev/null
+++ b/modules/stock_shipment_cost/stock.py
@@ -0,0 +1,253 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from decimal import Decimal
+
+from sql import Null
+
+from trytond.model import ModelView, Workflow, fields
+from trytond.modules.product import price_digits, round_price
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Eval, Bool
+from trytond.transaction import Transaction
+
+
+class Move(metaclass=PoolMeta):
+ __name__ = 'stock.move'
+
+ shipment_out_cost_price = fields.Numeric(
+ "Shipment Cost Price", digits=price_digits, readonly=True,
+ states={
+ 'invisible': ~Eval('shipment_out_cost_price'),
+ },
+ )
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls._allow_modify_closed_period.add('shipment_out_cost_price')
+
+
+class ShipmentCostMixin:
+ __slots__ = ()
+
+ carrier = fields.Many2One('carrier', 'Carrier', states={
+ 'readonly': Eval('shipment_cost_readonly', True),
+ })
+
+ cost_currency_used = fields.Function(fields.Many2One(
+ 'currency.currency', "Cost Currency",
+ states={
+ 'readonly': (
+ Eval('shipment_cost_readonly', True)
+ | ~Eval('cost_edit', False)),
+ }),
+ 'on_change_with_cost_currency_used', setter='set_cost')
+ cost_currency = fields.Many2One(
+ 'currency.currency', "Cost Currency",
+ states={
+ 'required': Bool(Eval('cost')),
+ 'readonly': Eval('shipment_cost_readonly', True),
+ })
+
+ cost_used = fields.Function(fields.Numeric(
+ "Cost", digits=price_digits,
+ states={
+ 'readonly': (
+ Eval('shipment_cost_readonly', True)
+ | ~Eval('cost_edit', False)),
+ }),
+ 'on_change_with_cost_used', setter='set_cost')
+ cost = fields.Numeric("Cost", digits=price_digits, readonly=True)
+ cost_edit = fields.Boolean(
+ "Edit Cost",
+ states={
+ 'readonly': Eval('shipment_cost_readonly', True),
+ 'invisible': Eval('shipment_cost_readonly', True),
+ },
+ help="Check to edit the cost.")
+
+ shipment_cost_readonly = fields.Function(
+ fields.Boolean("Shipment Cost Read Only"),
+ 'on_change_with_shipment_cost_readonly')
+
+ def _get_carrier_context(self):
+ return {}
+
+ def get_carrier_context(self):
+ return self._get_carrier_context()
+
+ @fields.depends('carrier', 'company', methods=['_get_carrier_context'])
+ def _compute_costs(self):
+ costs = {
+ 'cost': None,
+ 'cost_currency': None,
+ }
+ if self.carrier:
+ with Transaction().set_context(self._get_carrier_context()):
+ cost, currency_id = self.carrier.get_purchase_price()
+ if cost is not None:
+ costs['cost'] = round_price(cost)
+ costs['cost_currency'] = currency_id
+ return costs
+
+ @fields.depends(
+ 'cost_currency', 'cost_edit',
+ methods=['_compute_costs', 'on_change_with_shipment_cost_readonly'])
+ def on_change_with_cost_currency_used(self, name=None):
+ readonly = self.on_change_with_shipment_cost_readonly()
+ if not self.cost_edit and not readonly:
+ return self._compute_costs()['cost_currency']
+ elif self.cost_currency:
+ return self.cost_currency.id
+
+ @fields.depends(
+ 'cost', 'cost_edit',
+ methods=['_compute_costs', 'on_change_with_shipment_cost_readonly'])
+ def on_change_with_cost_used(self, name=None):
+ cost = self.cost
+ readonly = self.on_change_with_shipment_cost_readonly()
+ if not self.cost_edit and not readonly:
+ cost = self._compute_costs()['cost']
+ return cost
+
+ @classmethod
+ def set_cost(cls, lines, name, value):
+ if name.endswith('_used'):
+ name = name[:-len('_used')]
+ cls.write([l for l in lines if l.cost_edit], {
+ name: value,
+ })
+
+ def on_change_with_shipment_cost_readonly(self, name=None):
+ raise NotImplementedError
+
+ @classmethod
+ def index_set_field(cls, name):
+ index = super().index_set_field(name)
+ if name == 'cost_used':
+ index = cls.index_set_field('cost_currency_used') + 1
+ return index
+
+ @property
+ def shipment_cost_moves(self):
+ raise NotImplementedError
+
+ def _get_shipment_cost(self):
+ "Return the cost for the shipment in the company currency"
+ pool = Pool()
+ Currency = pool.get('currency.currency')
+ if self.cost_used:
+ return Currency.compute(
+ self.cost_currency_used, self.cost_used,
+ self.company.currency, round=False)
+ else:
+ return Decimal(0)
+
+
+class ShipmentOutCostMixin(ShipmentCostMixin):
+
+ @classmethod
+ def __register__(cls, module):
+ pool = Pool()
+ Company = pool.get('company.company')
+ table = cls.__table__()
+ table_h = cls.__table_handler__(module)
+ company = Company.__table__()
+ cursor = Transaction().connection.cursor()
+
+ cost_currency_exists = table_h.column_exist('cost_currency')
+
+ super().__register__(module)
+
+ # Migration from 6.4: fill cost_currency
+ if not cost_currency_exists:
+ cursor.execute(*table.update(
+ columns=[table.cost_currency],
+ values=[company.select(
+ company.currency,
+ where=company.id == table.company)],
+ where=table.cost != Null))
+
+ @fields.depends('state')
+ def on_change_with_shipment_cost_readonly(self, name=None):
+ return self.state in {'done', 'cancelled'}
+
+ @classmethod
+ def set_shipment_cost(cls, shipments):
+ pool = Pool()
+ Move = pool.get('stock.move')
+ moves = []
+ for shipment in shipments:
+ cost = shipment._get_shipment_cost()
+ if not cost:
+ continue
+ factors = getattr(shipment,
+ '_get_allocation_shipment_cost_factors_by_%s' %
+ shipment.allocation_shipment_cost_method)()
+ moves.extend(shipment._allocate_shipment_cost(cost, factors))
+ Move.save(moves)
+
+ @property
+ def allocation_shipment_cost_method(self):
+ if self.carrier:
+ return self.carrier.shipment_cost_allocation_method
+ return 'cost'
+
+ def _get_allocation_shipment_cost_factors_by_cost(self):
+ sum_ = Decimal(0)
+ costs = {}
+ for move in self.shipment_cost_moves:
+ move_cost = (
+ move.cost_price * Decimal(str(move.internal_quantity)))
+ costs[move] = move_cost
+ sum_ += move_cost
+
+ factors = {}
+ for move in self.shipment_cost_moves:
+ if sum_:
+ ratio = costs[move] / sum_
+ else:
+ ratio = Decimal(1) / len(self.shipment_cost_moves)
+ factors[move.id] = ratio
+ return factors
+
+ def _allocate_shipment_cost(self, cost, factors):
+ moves = []
+ for move in self.shipment_cost_moves:
+ ratio = factors[move.id]
+ quantity = Decimal(str(move.internal_quantity))
+ if quantity and ratio:
+ cost_price = round_price(cost * ratio / quantity)
+ else:
+ cost_price = Decimal(0)
+ if move.shipment_out_cost_price != cost_price:
+ move.shipment_out_cost_price = cost_price
+ moves.append(move)
+ return moves
+
+ @classmethod
+ @ModelView.button
+ @Workflow.transition('done')
+ def done(cls, shipments):
+ for shipment in shipments:
+ shipment.cost = shipment.cost_used
+ shipment.cost_currency = shipment.cost_currency_used
+ cls.save(shipments)
+ super().done(shipments)
+ cls.set_shipment_cost(shipments)
+
+
+class ShipmentOut(ShipmentOutCostMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out'
+
+ @property
+ def shipment_cost_moves(self):
+ return self.outgoing_moves
+
+
+class ShipmentOutReturn(ShipmentOutCostMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out.return'
+
+ @property
+ def shipment_cost_moves(self):
+ return self.incoming_moves
diff --git a/modules/stock_shipment_cost/stock.xml b/modules/stock_shipment_cost/stock.xml
new file mode 100644
index 0000000000..a37d781dd5
--- /dev/null
+++ b/modules/stock_shipment_cost/stock.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+ stock.move
+
+ stock_move_form
+
+
+
+ stock.shipment.out
+
+ shipment_out_form
+
+
+
+ stock.shipment.out.return
+
+ shipment_out_form
+
+
+
diff --git a/modules/stock_shipment_cost/stock_reporting_margin.py b/modules/stock_shipment_cost/stock_reporting_margin.py
new file mode 100644
index 0000000000..5f53dd664a
--- /dev/null
+++ b/modules/stock_shipment_cost/stock_reporting_margin.py
@@ -0,0 +1,32 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from sql.aggregate import Sum
+from sql.conditionals import Coalesce
+
+from trytond.model import fields
+from trytond.pool import PoolMeta
+from trytond.transaction import Transaction
+
+
+class AbstractShipmentOutCostMixin:
+ __slots__ = ()
+
+ @classmethod
+ def _column_cost(cls, tables, withs, sign):
+ move = tables['move']
+ cost = super()._column_cost(tables, withs, sign)
+ if Transaction().context.get('include_shipment_cost'):
+ cost += Sum(
+ sign * cls.cost.sql_cast(move.internal_quantity)
+ * Coalesce(move.shipment_out_cost_price, 0))
+ return cost
+
+
+class Context(metaclass=PoolMeta):
+ __name__ = 'stock.reporting.margin.context'
+
+ include_shipment_cost = fields.Boolean("Include Shipment Cost")
+
+ @classmethod
+ def default_include_shipment_cost(cls):
+ return Transaction().context.get('include_shipment_cost', False)
diff --git a/modules/stock_shipment_cost/stock_reporting_margin.xml b/modules/stock_shipment_cost/stock_reporting_margin.xml
new file mode 100644
index 0000000000..1b1430702a
--- /dev/null
+++ b/modules/stock_shipment_cost/stock_reporting_margin.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ stock.reporting.margin.context
+
+ reporting_margin_context_form
+
+
+
diff --git a/modules/stock_shipment_cost/tests/__init__.py b/modules/stock_shipment_cost/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_shipment_cost/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_shipment_cost/tests/scenario_stock_shipment_cost.rst b/modules/stock_shipment_cost/tests/scenario_stock_shipment_cost.rst
new file mode 100644
index 0000000000..8b6c93e63f
--- /dev/null
+++ b/modules/stock_shipment_cost/tests/scenario_stock_shipment_cost.rst
@@ -0,0 +1,126 @@
+============================
+Stock Shipment Cost Scenario
+============================
+
+Imports::
+
+ >>> import datetime as dt
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import (
+ ... create_company, get_company)
+ >>> today = dt.date.today()
+ >>> yesterday = today - dt.timedelta(days=1)
+
+Activate modules::
+
+ >>> config = activate_modules('stock_shipment_cost')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create customer::
+
+ >>> Party = Model.get('party.party')
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+
+Create products::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product1'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.save()
+ >>> product1, = template.products
+ >>> product1.cost_price = Decimal('10.0000')
+ >>> product1.save()
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product2'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.save()
+ >>> product2, = template.products
+ >>> product2.cost_price = Decimal('20.0000')
+ >>> product2.save()
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+
+Create a customer shipment::
+
+ >>> Shipment = Model.get('stock.shipment.out')
+ >>> shipment = Shipment()
+ >>> shipment.customer = customer
+ >>> move = shipment.outgoing_moves.new()
+ >>> move.product = product1
+ >>> move.quantity = 1
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> move.unit_price = Decimal('30')
+ >>> move.currency = company.currency
+ >>> move = shipment.outgoing_moves.new()
+ >>> move.product = product2
+ >>> move.quantity = 2
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> move.unit_price = Decimal('40')
+ >>> move.currency = company.currency
+ >>> shipment.click('wait')
+ >>> shipment.click('assign_force')
+ >>> shipment.click('pick')
+ >>> shipment.click('pack')
+ >>> shipment.cost_edit = True
+ >>> shipment.cost_used = Decimal('5')
+ >>> shipment.cost_currency_used = company.currency
+ >>> shipment.click('done')
+ >>> shipment.state
+ 'done'
+
+Check move costs::
+
+ >>> sorted([
+ ... (m.cost_price, m.shipment_out_cost_price)
+ ... for m in shipment.outgoing_moves])
+ [(Decimal('10.0000'), Decimal('1.0000')), (Decimal('20.0000'), Decimal('2.0000'))]
+
+Check reporting margin::
+
+ >>> MarginProduct = Model.get('stock.reporting.margin.product')
+ >>> MarginProductTimeseries = Model.get(
+ ... 'stock.reporting.margin.product.time_series')
+ >>> context = {
+ ... 'from_date': yesterday,
+ ... 'to_date': today,
+ ... 'period': 'day',
+ ... }
+ >>> with config.set_context(context=context):
+ ... reports = MarginProduct.find([])
+ ... time_series = MarginProductTimeseries.find([])
+ >>> len(reports)
+ 2
+ >>> sorted([r.cost for r in reports]) == [Decimal('10.0000'), Decimal('40.0000')]
+ True
+
+ >>> context['include_shipment_cost'] = True
+ >>> with config.set_context(context=context):
+ ... reports = MarginProduct.find([])
+ ... time_series = MarginProductTimeseries.find([])
+ >>> len(reports)
+ 2
+ >>> sorted([r.cost for r in reports]) == [Decimal('11.0000'), Decimal('44.0000')]
+ True
diff --git a/modules/stock_shipment_cost/tests/test_module.py b/modules/stock_shipment_cost/tests/test_module.py
new file mode 100644
index 0000000000..60e17807d7
--- /dev/null
+++ b/modules/stock_shipment_cost/tests/test_module.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockShipmentCostTestCase(ModuleTestCase):
+ 'Test Stock Shipment Cost module'
+ module = 'stock_shipment_cost'
+
+
+del ModuleTestCase
diff --git a/modules/stock_shipment_cost/tests/test_scenario.py b/modules/stock_shipment_cost/tests/test_scenario.py
new file mode 100644
index 0000000000..dc1d23e7e5
--- /dev/null
+++ b/modules/stock_shipment_cost/tests/test_scenario.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import load_doc_tests
+
+
+def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_shipment_cost/tox.ini b/modules/stock_shipment_cost/tox.ini
new file mode 100644
index 0000000000..b9a1f0e9bd
--- /dev/null
+++ b/modules/stock_shipment_cost/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_shipment_cost/* -m unittest discover -s tests
+ coverage report --include=./**/stock_shipment_cost/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_shipment_cost/tryton.cfg b/modules/stock_shipment_cost/tryton.cfg
new file mode 100644
index 0000000000..e3a5fba4f9
--- /dev/null
+++ b/modules/stock_shipment_cost/tryton.cfg
@@ -0,0 +1,11 @@
+[tryton]
+version=6.7.0
+depends:
+ carrier
+ ir
+ product
+ stock
+xml:
+ carrier.xml
+ stock.xml
+ stock_reporting_margin.xml
diff --git a/modules/stock_shipment_cost/view/carrier_form.xml b/modules/stock_shipment_cost/view/carrier_form.xml
new file mode 100644
index 0000000000..354a9e7529
--- /dev/null
+++ b/modules/stock_shipment_cost/view/carrier_form.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_shipment_cost/view/reporting_margin_context_form.xml b/modules/stock_shipment_cost/view/reporting_margin_context_form.xml
new file mode 100644
index 0000000000..686a16ce7f
--- /dev/null
+++ b/modules/stock_shipment_cost/view/reporting_margin_context_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_shipment_cost/view/shipment_out_form.xml b/modules/stock_shipment_cost/view/shipment_out_form.xml
new file mode 100644
index 0000000000..f5f5a5ac2f
--- /dev/null
+++ b/modules/stock_shipment_cost/view/shipment_out_form.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_shipment_cost/view/stock_move_form.xml b/modules/stock_shipment_cost/view/stock_move_form.xml
new file mode 100644
index 0000000000..7a86b5f9d6
--- /dev/null
+++ b/modules/stock_shipment_cost/view/stock_move_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_shipment_cost_weight/.drone.yml b/modules/stock_shipment_cost_weight/.drone.yml
new file mode 100644
index 0000000000..b45ef267ef
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/.drone.yml
@@ -0,0 +1,78 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+ check_doc:
+ image: ${IMAGE}
+ commands:
+ - pip install sphinx
+ - python -m sphinx -T -E -W -n -b html doc _build/html
+ - python -m sphinx -T -E -W -n -b linkcheck doc _build
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_shipment_cost_weight/.flake8 b/modules/stock_shipment_cost_weight/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_shipment_cost_weight/.isort.cfg b/modules/stock_shipment_cost_weight/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_shipment_cost_weight/CHANGELOG b/modules/stock_shipment_cost_weight/CHANGELOG
new file mode 100644
index 0000000000..7a287d58a2
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/CHANGELOG
@@ -0,0 +1,7 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+--------------------------
+* Initial release
diff --git a/modules/stock_shipment_cost_weight/COPYRIGHT b/modules/stock_shipment_cost_weight/COPYRIGHT
new file mode 100644
index 0000000000..f8f170606e
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2022 B2CK
+Copyright (C) 2022 Cédric Krier
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_shipment_cost_weight/LICENSE b/modules/stock_shipment_cost_weight/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_shipment_cost_weight/MANIFEST.in b/modules/stock_shipment_cost_weight/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_shipment_cost_weight/README.rst b/modules/stock_shipment_cost_weight/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_shipment_cost_weight/__init__.py b/modules/stock_shipment_cost_weight/__init__.py
new file mode 100644
index 0000000000..d0ce2098ea
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/__init__.py
@@ -0,0 +1,16 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import carrier, stock
+
+__all__ = ['register']
+
+
+def register():
+ Pool.register(
+ carrier.Carrier,
+ stock.ShipmentOut,
+ stock.ShipmentOutReturn,
+ module='stock_shipment_cost_weight', type_='model')
diff --git a/modules/stock_shipment_cost_weight/carrier.py b/modules/stock_shipment_cost_weight/carrier.py
new file mode 100644
index 0000000000..3e7030fcbe
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/carrier.py
@@ -0,0 +1,14 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import PoolMeta
+
+
+class Carrier(metaclass=PoolMeta):
+ __name__ = 'carrier'
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls.shipment_cost_allocation_method.selection.append(
+ ('weight', "By Weight"))
diff --git a/modules/stock_shipment_cost_weight/doc/conf.py b/modules/stock_shipment_cost_weight/doc/conf.py
new file mode 100644
index 0000000000..8513b72dd2
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/doc/conf.py
@@ -0,0 +1,61 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+modules_url = 'https://docs.tryton.org/projects/modules-{module}/en/{series}/'
+trytond_url = 'https://docs.tryton.org/projects/server/en/{series}/'
+
+
+def get_info():
+ import configparser
+ import os
+ import subprocess
+ import sys
+
+ module_dir = os.path.dirname(os.path.dirname(__file__))
+
+ config = configparser.ConfigParser()
+ config.read_file(open(os.path.join(module_dir, 'tryton.cfg')))
+ info = dict(config.items('tryton'))
+
+ result = subprocess.run(
+ [sys.executable, 'setup.py', '--name'],
+ stdout=subprocess.PIPE, check=True, cwd=module_dir)
+ info['name'] = result.stdout.decode('utf-8').strip()
+
+ result = subprocess.run(
+ [sys.executable, 'setup.py', '--version'],
+ stdout=subprocess.PIPE, check=True, cwd=module_dir)
+ version = result.stdout.decode('utf-8').strip()
+ if 'dev' in version:
+ info['series'] = 'latest'
+ else:
+ info['series'] = '.'.join(version.split('.', 2)[:2])
+
+ for key in {'depends', 'extras_depend'}:
+ info[key] = info.get(key, '').strip().splitlines()
+ info['modules'] = set(info['depends'] + info['extras_depend'])
+ info['modules'] -= {'ir', 'res'}
+
+ return info
+
+
+info = get_info()
+
+master_doc = 'index'
+project = info['name']
+release = version = info['series']
+default_role = 'ref'
+highlight_language = 'none'
+extensions = [
+ 'sphinx.ext.intersphinx',
+ ]
+intersphinx_mapping = {
+ 'trytond': (trytond_url.format(series=version), None),
+ }
+intersphinx_mapping.update({
+ m: (modules_url.format(
+ module=m.replace('_', '-'), series=version), None)
+ for m in info['modules']
+ })
+
+del get_info, info, modules_url, trytond_url
diff --git a/modules/stock_shipment_cost_weight/doc/index.rst b/modules/stock_shipment_cost_weight/doc/index.rst
new file mode 100644
index 0000000000..41a9b97b68
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/doc/index.rst
@@ -0,0 +1,11 @@
+#################################
+Stock Shipment Cost Weight Module
+#################################
+
+The *Stock Shipment Cost Weight Module* adds "By Weight" as allocation method of
+shipment cost on the carrier.
+
+.. toctree::
+ :maxdepth: 2
+
+ releases
diff --git a/modules/stock_shipment_cost_weight/doc/releases.rst b/modules/stock_shipment_cost_weight/doc/releases.rst
new file mode 100644
index 0000000000..21b13c4745
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/doc/releases.rst
@@ -0,0 +1,7 @@
+.. _releases-index:
+
+=============
+Release notes
+=============
+
+.. include:: ../CHANGELOG
diff --git a/modules/stock_shipment_cost_weight/locale/bg.po b/modules/stock_shipment_cost_weight/locale/bg.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/bg.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/ca.po b/modules/stock_shipment_cost_weight/locale/ca.po
new file mode 100644
index 0000000000..ccd0abc0a9
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/ca.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr "Per pes"
diff --git a/modules/stock_shipment_cost_weight/locale/cs.po b/modules/stock_shipment_cost_weight/locale/cs.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/cs.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/de.po b/modules/stock_shipment_cost_weight/locale/de.po
new file mode 100644
index 0000000000..2844bd7c42
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/de.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr "Nach Gewicht"
diff --git a/modules/stock_shipment_cost_weight/locale/es.po b/modules/stock_shipment_cost_weight/locale/es.po
new file mode 100644
index 0000000000..2c2ff850ae
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/es.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr "Por peso"
diff --git a/modules/stock_shipment_cost_weight/locale/es_419.po b/modules/stock_shipment_cost_weight/locale/es_419.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/es_419.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/et.po b/modules/stock_shipment_cost_weight/locale/et.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/et.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/fa.po b/modules/stock_shipment_cost_weight/locale/fa.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/fa.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/fi.po b/modules/stock_shipment_cost_weight/locale/fi.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/fi.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/fr.po b/modules/stock_shipment_cost_weight/locale/fr.po
new file mode 100644
index 0000000000..a07b07e3b0
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/fr.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr "Par poids"
diff --git a/modules/stock_shipment_cost_weight/locale/hu.po b/modules/stock_shipment_cost_weight/locale/hu.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/hu.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/id.po b/modules/stock_shipment_cost_weight/locale/id.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/id.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/it.po b/modules/stock_shipment_cost_weight/locale/it.po
new file mode 100644
index 0000000000..b282901d02
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/it.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr "Per peso"
diff --git a/modules/stock_shipment_cost_weight/locale/lo.po b/modules/stock_shipment_cost_weight/locale/lo.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/lo.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/lt.po b/modules/stock_shipment_cost_weight/locale/lt.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/lt.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/nl.po b/modules/stock_shipment_cost_weight/locale/nl.po
new file mode 100644
index 0000000000..42e53ef73c
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/nl.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr "Op gewicht"
diff --git a/modules/stock_shipment_cost_weight/locale/pl.po b/modules/stock_shipment_cost_weight/locale/pl.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/pl.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/pt.po b/modules/stock_shipment_cost_weight/locale/pt.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/pt.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/ro.po b/modules/stock_shipment_cost_weight/locale/ro.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/ro.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/ru.po b/modules/stock_shipment_cost_weight/locale/ru.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/ru.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/sl.po b/modules/stock_shipment_cost_weight/locale/sl.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/sl.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/tr.po b/modules/stock_shipment_cost_weight/locale/tr.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/tr.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/uk.po b/modules/stock_shipment_cost_weight/locale/uk.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/uk.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/locale/zh_CN.po b/modules/stock_shipment_cost_weight/locale/zh_CN.po
new file mode 100644
index 0000000000..fe41a51be5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/locale/zh_CN.po
@@ -0,0 +1,7 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "selection:carrier,shipment_cost_allocation_method:"
+msgid "By Weight"
+msgstr ""
diff --git a/modules/stock_shipment_cost_weight/setup.py b/modules/stock_shipment_cost_weight/setup.py
new file mode 100755
index 0000000000..3ace720d34
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/setup.py
@@ -0,0 +1,158 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ content = io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+ content = re.sub(
+ r'(?m)^\.\. toctree::\r?\n((^$|^\s.*$)\r?\n)*', '', content)
+ return content
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_shipment_cost_weight'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+requires = []
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [get_require_version('proteus')]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version)
+ )
+
+setup(name=name,
+ version=version,
+ description='Tryton module to allocate shipment cost "by weight"',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": (
+ 'https://docs.tryton.org/projects/'
+ 'modules-stock-shipment-cost-weight'),
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": (
+ 'https://hg.tryton.org/modules/stock_shipment_cost_weight'),
+ },
+ keywords='tryton stock shipment cost weight',
+ package_dir={'trytond.modules.stock_shipment_cost_weight': '.'},
+ packages=(
+ ['trytond.modules.stock_shipment_cost_weight']
+ + ['trytond.modules.stock_shipment_cost_weight.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_shipment_cost_weight': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_shipment_cost_weight = trytond.modules.stock_shipment_cost_weight
+ """, # noqa: E501
+ )
diff --git a/modules/stock_shipment_cost_weight/stock.py b/modules/stock_shipment_cost_weight/stock.py
new file mode 100644
index 0000000000..5d0f1c4d99
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/stock.py
@@ -0,0 +1,37 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from decimal import Decimal
+
+from trytond.pool import Pool, PoolMeta
+
+
+class ShipmentCostMixinWeight:
+ __slots__ = ()
+
+ def _get_allocation_shipment_cost_factors_by_weight(self):
+ pool = Pool()
+ Move = pool.get('stock.move')
+ if getattr(Move, 'internal_weight', None):
+ sum_weight = Decimal(0)
+ weights = {}
+ for move in self.shipment_cost_moves:
+ weight = Decimal(str(move.internal_weight or 0))
+ weights[move.id] = weight
+ sum_weight += weight
+
+ if sum_weight:
+ factors = {}
+ for move in self.shipment_cost_moves:
+ factors[move.id] = weights[move.id] / sum_weight
+ return factors
+ return self._get_allocation_shipment_cost_factors_by_cost()
+
+
+class ShipmentOut(ShipmentCostMixinWeight, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out'
+
+
+class ShipmentOutReturn(
+ ShipmentCostMixinWeight, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out.return'
diff --git a/modules/stock_shipment_cost_weight/tests/__init__.py b/modules/stock_shipment_cost_weight/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_shipment_cost_weight/tests/scenario_stock_shipment_cost_weight.rst b/modules/stock_shipment_cost_weight/tests/scenario_stock_shipment_cost_weight.rst
new file mode 100644
index 0000000000..861b446807
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/tests/scenario_stock_shipment_cost_weight.rst
@@ -0,0 +1,122 @@
+===================================
+Stock Shipment Cost Weight Scenario
+===================================
+
+Imports::
+
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import (
+ ... create_company, get_company)
+
+Patch _get_shipment_cost::
+
+ >>> from unittest.mock import patch
+ >>> from trytond.modules.stock_shipment_cost.stock import ShipmentCostMixin
+ >>> mock = patch.object(
+ ... ShipmentCostMixin, '_get_shipment_cost',
+ ... return_value=Decimal('8')).start()
+
+Activate modules::
+
+ >>> config = activate_modules('stock_shipment_cost_weight')
+
+ >>> Carrier = Model.get('carrier')
+ >>> Location = Model.get('stock.location')
+ >>> Party = Model.get('party.party')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> ProductUom = Model.get('product.uom')
+ >>> Shipment = Model.get('stock.shipment.out')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create customer::
+
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+
+Create products::
+
+ >>> unit, = ProductUom.find([('name', '=', "Unit")])
+ >>> gram, = ProductUom.find([('name', '=', "Gram")])
+
+ >>> template = ProductTemplate()
+ >>> template.name = "Product1"
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.weight = 500
+ >>> template.weight_uom = gram
+ >>> template.save()
+ >>> product1, = template.products
+ >>> product1.cost_price = Decimal('10.0000')
+ >>> product1.save()
+
+ >>> template = ProductTemplate()
+ >>> template.name = "Product2"
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.weight = 250
+ >>> template.weight_uom = gram
+ >>> template.save()
+ >>> product2, = template.products
+ >>> product2.cost_price = Decimal('20.0000')
+ >>> product2.save()
+
+ >>> carrier_template = ProductTemplate()
+ >>> carrier_template.name = "Carrier Product"
+ >>> carrier_template.default_uom = unit
+ >>> carrier_template.type = 'service'
+ >>> carrier_template.save()
+ >>> carrier_product, = carrier_template.products
+
+Create carrier::
+
+ >>> carrier = Carrier()
+ >>> carrier.party = Party(name="Carrier")
+ >>> carrier.party.save()
+ >>> carrier.carrier_product = carrier_product
+ >>> carrier.shipment_cost_allocation_method = 'weight'
+ >>> carrier.save()
+
+Get stock locations::
+
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+
+Create a customer shipment::
+
+ >>> shipment = Shipment()
+ >>> shipment.customer = customer
+ >>> shipment.carrier = carrier
+ >>> move = shipment.outgoing_moves.new()
+ >>> move.product = product1
+ >>> move.quantity = 1
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> move.unit_price = Decimal('30')
+ >>> move.currency = company.currency
+ >>> move = shipment.outgoing_moves.new()
+ >>> move.product = product2
+ >>> move.quantity = 2
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> move.unit_price = Decimal('40')
+ >>> move.currency = company.currency
+ >>> shipment.click('wait')
+ >>> shipment.click('assign_force')
+ >>> shipment.click('pick')
+ >>> shipment.click('pack')
+ >>> shipment.click('done')
+ >>> shipment.state
+ 'done'
+
+Check move costs::
+
+ >>> sorted([
+ ... (m.cost_price, m.shipment_out_cost_price)
+ ... for m in shipment.outgoing_moves])
+ [(Decimal('10.0000'), Decimal('4.0000')), (Decimal('20.0000'), Decimal('2.0000'))]
diff --git a/modules/stock_shipment_cost_weight/tests/test_module.py b/modules/stock_shipment_cost_weight/tests/test_module.py
new file mode 100644
index 0000000000..79194bf53d
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/tests/test_module.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockShipmentCostWeightTestCase(ModuleTestCase):
+ 'Test Stock Shipment Cost Weight module'
+ module = 'stock_shipment_cost_weight'
+
+
+del ModuleTestCase
diff --git a/modules/stock_shipment_cost_weight/tests/test_scenario.py b/modules/stock_shipment_cost_weight/tests/test_scenario.py
new file mode 100644
index 0000000000..dc1d23e7e5
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/tests/test_scenario.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import load_doc_tests
+
+
+def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_shipment_cost_weight/tox.ini b/modules/stock_shipment_cost_weight/tox.ini
new file mode 100644
index 0000000000..761dc3d803
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_shipment_cost_weight/* -m unittest discover -s tests
+ coverage report --include=./**/stock_shipment_cost_weight/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_shipment_cost_weight/tryton.cfg b/modules/stock_shipment_cost_weight/tryton.cfg
new file mode 100644
index 0000000000..266fa4fdff
--- /dev/null
+++ b/modules/stock_shipment_cost_weight/tryton.cfg
@@ -0,0 +1,7 @@
+[tryton]
+version=6.7.0
+depends:
+ carrier
+ ir
+ stock_shipment_cost
+ stock_shipment_measurements
diff --git a/modules/stock_shipment_measurements/.drone.yml b/modules/stock_shipment_measurements/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_shipment_measurements/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_shipment_measurements/.flake8 b/modules/stock_shipment_measurements/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_shipment_measurements/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_shipment_measurements/.isort.cfg b/modules/stock_shipment_measurements/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_shipment_measurements/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_shipment_measurements/CHANGELOG b/modules/stock_shipment_measurements/CHANGELOG
new file mode 100644
index 0000000000..57a126f4bd
--- /dev/null
+++ b/modules/stock_shipment_measurements/CHANGELOG
@@ -0,0 +1,43 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Use configured unit for measurements
+* Add packages weight
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+* Include additional package weight to weight parcel
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+* Initial release
diff --git a/modules/stock_shipment_measurements/COPYRIGHT b/modules/stock_shipment_measurements/COPYRIGHT
new file mode 100644
index 0000000000..585f9c6f67
--- /dev/null
+++ b/modules/stock_shipment_measurements/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2017-2022 Cédric Krier
+Copyright (C) 2017-2022 B2CK
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_shipment_measurements/LICENSE b/modules/stock_shipment_measurements/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_shipment_measurements/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_shipment_measurements/MANIFEST.in b/modules/stock_shipment_measurements/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_shipment_measurements/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_shipment_measurements/README.rst b/modules/stock_shipment_measurements/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_shipment_measurements/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_shipment_measurements/__init__.py b/modules/stock_shipment_measurements/__init__.py
new file mode 100644
index 0000000000..012cf2e8bd
--- /dev/null
+++ b/modules/stock_shipment_measurements/__init__.py
@@ -0,0 +1,30 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import stock
+
+__all__ = ['register']
+
+
+def register():
+ Pool.register(
+ stock.Configuration,
+ stock.ConfigurationMeasurement,
+ stock.Move,
+ stock.ShipmentIn,
+ stock.ShipmentInReturn,
+ stock.ShipmentOut,
+ stock.ShipmentOutReturn,
+ module='stock_shipment_measurements', type_='model')
+ Pool.register(
+ stock.Package,
+ stock.ShipmentOutPackage,
+ stock.ShipmentInReturnPackage,
+ module='stock_shipment_measurements', type_='model',
+ depends=['stock_package'])
+ Pool.register(
+ module='stock_shipment_measurements', type_='wizard')
+ Pool.register(
+ module='stock_shipment_measurements', type_='report')
diff --git a/modules/stock_shipment_measurements/doc/index.rst b/modules/stock_shipment_measurements/doc/index.rst
new file mode 100644
index 0000000000..4a51366782
--- /dev/null
+++ b/modules/stock_shipment_measurements/doc/index.rst
@@ -0,0 +1,6 @@
+Stock Shipment Measurements Module
+##################################
+
+The Stock Shipment Measurements module adds weight and volume on shipments and
+packages.
+They are computed using the measurement and the quantity of their moves.
diff --git a/modules/stock_shipment_measurements/locale/bg.po b/modules/stock_shipment_measurements/locale/bg.po
new file mode 100644
index 0000000000..05ab686bf9
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/bg.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr ""
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr ""
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr ""
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr ""
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr ""
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/ca.po b/modules/stock_shipment_measurements/locale/ca.po
new file mode 100644
index 0000000000..90dcff53f1
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/ca.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr "UdM de mesura del volum"
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr "UdM de mesura del pes"
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr "UdM de mesura del volum"
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr "UdM de mesura del pes"
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr "Volum intern"
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr "Pes intern"
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr "Pes addicional"
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr "UdM del pes addicional"
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr "Volum total"
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr "Pes total"
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr "Volum"
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr "UdM del volum"
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr "Pes"
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr "UdM del pes"
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr "Volum"
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr "UdM del volum"
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr "Pes"
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr "UdM del pes"
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr "Volum dels paquets"
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr "Pes dels paquets"
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr "Volum"
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "UdM del volum"
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr "Pes"
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "UdM del pes"
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr "Volum dels paquets"
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr "Pes dels paquets"
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr "Volum"
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr "UdM del volum"
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr "Pes"
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr "UdM del pes"
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr "Volum"
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "UdM del volum"
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr "Pes"
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "UdM del pes"
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr "El volum en litres del producte mogut."
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr "El pes en kilograms del producte mogut."
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr "El pes a afegir als paquets."
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr "El volum total dels paquets."
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr "El pes total dels paquets."
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr "El volum total dels moviments del registre."
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr "El pes total dels moviments del registre."
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr "El volum total dels moviments del registre."
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr "El pes total dels moviments del registre."
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "El volum total dels paquets."
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "El pes total dels paquets."
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "El volum total dels moviments del registre."
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "El pes total dels moviments del registre."
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "El volum total dels paquets."
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "El pes total dels paquets."
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr "El volum total dels moviments del registre."
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr "El pes total dels moviments del registre."
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "El volum total dels moviments del registre."
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "El pes total dels moviments del registre."
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr "Configuració de les mesures de logística"
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr "Mesures"
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr "Volum"
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr "Pes"
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr "Mesures"
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr "Mesures"
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr "Mesures"
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr "Mesures"
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr "Mesures"
diff --git a/modules/stock_shipment_measurements/locale/cs.po b/modules/stock_shipment_measurements/locale/cs.po
new file mode 100644
index 0000000000..05ab686bf9
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/cs.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr ""
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr ""
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr ""
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr ""
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr ""
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/de.po b/modules/stock_shipment_measurements/locale/de.po
new file mode 100644
index 0000000000..09c947a0a2
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/de.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr "Volumeneinheit"
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr "Gewichtseinheit"
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr "Unternehmen"
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr "Volumeneinheit"
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr "Gewichtseinheit"
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr "Internes Volumen"
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr "Internes Gewicht"
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr "Zusätzliches Gewicht"
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr "Maßeinheit Zusätzliches Gewicht"
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr "Gesamtvolumen"
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr "Gesamtgewicht"
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr "Volumen"
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volumeneinheit"
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr "Gewicht"
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr "Gewichtseinheit"
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr "Volumen"
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volumeneinheit"
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr "Gewicht"
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr "Gewichtseinheit"
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr "Paketvolumen"
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr "Paketgewicht"
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr "Volumen"
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volumeneinheit"
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr "Gewicht"
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "Gewichtseinheit"
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr "Paketvolumen"
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr "Paketgewicht"
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr "Volumen"
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volumeneinheit"
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr "Gewicht"
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr "Gewichtseinheit"
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr "Volumen"
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volumeneinheit"
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr "Gewicht"
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "Gewichtseinheit"
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr "Das Volumen des bewegten Artikels in Liter."
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr "Das Gewicht des bewegten Artikels in kg."
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr "Das zu den Paketen hinzuzurechnende Gewicht."
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr "Das Gesamtvolumen der Pakete."
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr "Das Gesamtgewicht der Pakete."
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Das Gesamtvolumen der Warenbewegungen des Datensatzes."
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Das Gesamtgewicht der Warenbewegungen des Datensatzes."
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Das Gesamtvolumen der Warenbewegungen des Datensatzes."
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Das Gesamtgewicht der Warenbewegungen des Datensatzes."
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "Das Gesamtvolumen der Pakete."
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "Das Gesamtgewicht der Pakete."
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Das Gesamtvolumen der Warenbewegungen des Datensatzes."
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Das Gesamtgewicht der Warenbewegungen des Datensatzes."
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "Das Gesamtvolumen der Pakete."
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "Das Gesamtgewicht der Pakete."
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Das Gesamtvolumen der Warenbewegungen des Datensatzes."
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Das Gesamtgewicht der Warenbewegungen des Datensatzes."
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Das Gesamtvolumen der Warenbewegungen des Datensatzes."
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Das Gesamtgewicht der Warenbewegungen des Datensatzes."
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr "Lager Einstellungen Abmessungen"
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr "Abmessungen"
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr "Volumen"
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr "Gewicht"
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr "Abmessungen"
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr "Abmessungen"
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr "Abmessungen"
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr "Abmessungen"
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr "Abmessungen"
diff --git a/modules/stock_shipment_measurements/locale/es.po b/modules/stock_shipment_measurements/locale/es.po
new file mode 100644
index 0000000000..7506f2a0e6
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/es.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr "Unidad de la medida volumen"
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr "Unidad de la medida peso"
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr "Unidad de la medida volumen"
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr "Unidad de la medida peso"
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr "Volumen interno"
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr "Peso interno"
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr "Peso adicional"
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr "Unidad del peso adicional"
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr "Volumen total"
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr "Peso total"
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr "Volumen"
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr "Unidad del volumen"
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr "Peso"
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr "Unidad del peso"
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr "Volumen"
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr "Unidad del volumen"
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr "Peso"
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr "Unidad del peso"
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr "Volumen de los paquetes"
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr "Peso de los paquetes"
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr "Volumen"
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "Unidad del volumen"
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr "Peso"
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "Unidad del peso"
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr "Volumen de los paquetes"
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr "Peso de los paquetes"
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr "Volumen"
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr "Unidad del volumen"
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr "Peso"
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr "Unidad del peso"
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr "Volumen"
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "Unidad del volumen"
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr "Peso"
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "Unidad del peso"
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr "El volumen en litros del producto movido."
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr "El peso en kilogramos del producto movido."
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr "El peso a añadir a los paquetes."
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr "El volumen total de los paquetes."
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr "El peso total de los paquetes."
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr "El volumen total de los movimientos del registro."
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr "El peso total de los movimientos del registro."
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr "El volumen total de los movimientos del registro."
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr "El peso total de los movimientos del registro."
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "El volumen total de los paquetes."
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "El peso total de los paquetes."
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "El volumen total de los movimientos del registro."
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "El peso total de los movimientos del registro."
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "El volumen total de los paquetes."
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "El peso total de los paquetes."
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr "El volumen total de los movimientos del registro."
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr "El peso total de los movimientos del registro."
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "El volumen total de los movimientos del registro."
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "El peso total de los movimientos del registro."
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr "Configuración de las medidas de logística"
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr "Medidas"
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr "Volumen"
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr "Peso"
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr "Medidas"
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr "Medidas"
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr "Medidas"
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr "Medidas"
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr "Medidas"
diff --git a/modules/stock_shipment_measurements/locale/es_419.po b/modules/stock_shipment_measurements/locale/es_419.po
new file mode 100644
index 0000000000..05ab686bf9
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/es_419.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr ""
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr ""
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr ""
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr ""
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr ""
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/et.po b/modules/stock_shipment_measurements/locale/et.po
new file mode 100644
index 0000000000..20a857b243
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/et.po
@@ -0,0 +1,285 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr "Sisemine maht"
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr "Sisemine kaal"
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr "Täiendav kaal"
+
+#, fuzzy
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr "Täiendav kaal"
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr "Maht kokku"
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr "Kaal kokku"
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr "Maht"
+
+#, fuzzy
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr "Maht"
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr "Kaal"
+
+#, fuzzy
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr "Kaal"
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr "Maht"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr "Maht"
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr "Kaal"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr "Kaal"
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr "Maht"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "Maht"
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr "Kaal"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "Kaal"
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr "Maht"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr "Maht"
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr "Kaal"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr "Kaal"
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr "Maht"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "Maht"
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr "Kaal"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "Kaal"
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr "Liigutatud kauba maht liitrites."
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr "Liigutatud kauba kaal kilogrammides."
+
+#, fuzzy
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr "Pakenditele lisatav kaal kilogrammides."
+
+#, fuzzy
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr "Pakendite kogumaht liitrites."
+
+#, fuzzy
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr "Pakendite kogukaal kilogrammides."
+
+#, fuzzy
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Kirjete kogumaht liitrites."
+
+#, fuzzy
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Kirje kogukaal kilogrammides."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Kirjete kogumaht liitrites."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Kirje kogukaal kilogrammides."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "Pakendite kogumaht liitrites."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "Pakendite kogukaal kilogrammides."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Kirjete kogumaht liitrites."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Kirje kogukaal kilogrammides."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "Pakendite kogumaht liitrites."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "Pakendite kogukaal kilogrammides."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Kirjete kogumaht liitrites."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Kirje kogukaal kilogrammides."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Kirjete kogumaht liitrites."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Kirje kogukaal kilogrammides."
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr "Maht"
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr "Kaal"
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/fa.po b/modules/stock_shipment_measurements/locale/fa.po
new file mode 100644
index 0000000000..8684540b72
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/fa.po
@@ -0,0 +1,285 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr "حجم داخلی"
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr "وزن داخلی"
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr "وزن اضافی"
+
+#, fuzzy
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr "وزن اضافی"
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr "مجموع حجم"
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr "مجموع وزن"
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr "حجم"
+
+#, fuzzy
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr "حجم"
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr "وزن"
+
+#, fuzzy
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr "وزن"
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr "حجم"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr "حجم"
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr "وزن"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr "وزن"
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr "حجم"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "حجم"
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr "وزن"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "وزن"
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr "حجم"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr "حجم"
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr "وزن"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr "وزن"
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr "حجم"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "حجم"
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr "وزن"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "وزن"
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr "مقدار حجم جابجا شده محصول در لیتر."
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr "مقدار وزن جابجا شده محصول در کیلوگرم."
+
+#, fuzzy
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr "وزن برای اضافه کردن به بسته ها در کیلوگرم."
+
+#, fuzzy
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr "مجموع حجم محصول در لیتر."
+
+#, fuzzy
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr "وزن کل بسته ها در کیلوگرم."
+
+#, fuzzy
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr "مجموع حجم جابجایی پرونده ها در لیتر."
+
+#, fuzzy
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr "مجموع وزن جابجایی پرونده ها در کیلوگرم."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr "مجموع حجم جابجایی پرونده ها در لیتر."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr "مجموع وزن جابجایی پرونده ها در کیلوگرم."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "مجموع حجم محصول در لیتر."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "وزن کل بسته ها در کیلوگرم."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "مجموع حجم جابجایی پرونده ها در لیتر."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "مجموع وزن جابجایی پرونده ها در کیلوگرم."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "مجموع حجم محصول در لیتر."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "وزن کل بسته ها در کیلوگرم."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr "مجموع حجم جابجایی پرونده ها در لیتر."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr "مجموع وزن جابجایی پرونده ها در کیلوگرم."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "مجموع حجم جابجایی پرونده ها در لیتر."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "مجموع وزن جابجایی پرونده ها در کیلوگرم."
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr "حجم"
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr "وزن"
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/fi.po b/modules/stock_shipment_measurements/locale/fi.po
new file mode 100644
index 0000000000..05ab686bf9
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/fi.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr ""
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr ""
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr ""
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr ""
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr ""
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/fr.po b/modules/stock_shipment_measurements/locale/fr.po
new file mode 100644
index 0000000000..bedf61cc6d
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/fr.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr "Mesure de volume UDM"
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr "Mesure de poids UDM"
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr "Société"
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr "Mesure de volume UDM"
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr "Mesure de poids UDM"
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr "Volume interne"
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr "Poids interne"
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr "Poids supplémentaire"
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr "Poids supplémentaire UDM"
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr "Volume total"
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr "Poids total"
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr "Volume"
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr "UDM de volume"
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr "Poids"
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr "UDM de poids"
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr "Volume"
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr "UDM de volume"
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr "Poids"
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr "UDM de poids"
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr "Volume des emballages"
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr "Poids des emballages"
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr "Volume"
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "UDM de volume"
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr "Poids"
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "UDM de poids"
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr "Volume des emballages"
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr "Poids des emballages"
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr "Volume"
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr "UDM de volume"
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr "Poids"
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr "UDM de poids"
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr "Volume"
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "UDM de volume"
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr "Poids"
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "UDM de poids"
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr "Le volume des produits déplacés en litre."
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr "Le poids des produits déplacés en kg."
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr "Le poids à ajouter aux emballages."
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr "Le volume total des emballages."
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr "Le poids total des emballage."
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Le volume total des mouvements de l'enregistrement."
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Le poids total des mouvements de l'enregistrement."
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Le volume total des mouvements de l'enregistrement."
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Le poids total des mouvements de l'enregistrement."
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "Le volume total des emballages."
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "Le poids total des emballages."
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Le volume total des mouvements de l'enregistrement."
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Le poids total des mouvements de l'enregistrement."
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "Le volume total des emballages."
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "Le poids total des emballages."
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Le volume total des mouvements de l'enregistrement."
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Le poids total des mouvements de l'enregistrement."
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Le volume total des mouvements de l'enregistrement."
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Le poids total des mouvements de l'enregistrement."
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr "Configuration de stock Mesure"
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr "Mesures"
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr "Volume"
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr "Poids"
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr "Mesures"
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr "Mesures"
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr "Mesures"
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr "Mesures"
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr "Mesures"
diff --git a/modules/stock_shipment_measurements/locale/hu.po b/modules/stock_shipment_measurements/locale/hu.po
new file mode 100644
index 0000000000..05ab686bf9
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/hu.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr ""
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr ""
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr ""
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr ""
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr ""
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/id.po b/modules/stock_shipment_measurements/locale/id.po
new file mode 100644
index 0000000000..33f4c99fec
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/id.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr "Perusahaan"
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr ""
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr ""
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr ""
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr ""
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr ""
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/it.po b/modules/stock_shipment_measurements/locale/it.po
new file mode 100644
index 0000000000..05ab686bf9
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/it.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr ""
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr ""
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr ""
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr ""
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr ""
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/lo.po b/modules/stock_shipment_measurements/locale/lo.po
new file mode 100644
index 0000000000..05ab686bf9
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/lo.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr ""
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr ""
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr ""
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr ""
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr ""
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/lt.po b/modules/stock_shipment_measurements/locale/lt.po
new file mode 100644
index 0000000000..05ab686bf9
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/lt.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr ""
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr ""
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr ""
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr ""
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr ""
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/nl.po b/modules/stock_shipment_measurements/locale/nl.po
new file mode 100644
index 0000000000..1366ae544f
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/nl.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr "Maateenheid afmeting volume"
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr "Maateenheid afmeting gewicht"
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr "Bedrijf"
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr "Maateenheid afmeting volume"
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr "Maateenheid afmeting gewicht"
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr "Intern volumes"
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr "Intern gewicht"
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr "Extra gewicht"
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr "Maateenheid extra gewicht"
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr "Totaal volume"
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr "totaal gewicht"
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr "Volume"
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr "Maateenheid volume"
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr "Gewicht"
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr "Maateenheid gewicht"
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr "Volume"
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr "Maateenheid volume"
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr "Gewicht"
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr "Maateenheid gewicht"
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr "Volume verpakkingen"
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr "Gewicht verpakkingen"
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr "Volume"
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "Maateenheid volume"
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr "Gewicht"
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "Maateenheid gewicht"
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr "Volume verpakkingen"
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr "Gewicht verpakkingen"
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr "Volume"
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr "Maateenheid volume"
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr "Gewicht"
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr "Maateenheid gewicht"
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr "Volume"
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volume maateenhied"
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr "Gewicht"
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "Maateenheid gewicht"
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr "Het volume van het verplaatste product in liter."
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr "Het gewicht van het verplaatste product in kg."
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr "Het gewicht dat moet worden toegevoegd aan de pakketten."
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr "Het totale volume van de pakketten."
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr "Het totale gewicht van de pakketten."
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Het totale volume van de voorraadbewegingen."
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Het totale gewicht van de voorraadbewegingen."
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Het totale volume van de voorraadbewegingen."
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Het totale gewicht van de voorraadbewegingen."
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "Het totale volume van de pakketten."
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "Het totale gewicht van de pakketten."
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Het totale volume van de voorraadbewegingen."
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Het totale gewicht van de voorraadbewegingen."
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "Het totale volume van de pakketten."
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "Het totale gewicht van de pakketten."
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Het totale volume van de voorraadbewegingen."
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Het totale gewicht van de voorraadbewegingen."
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Het totale volume van de voorraadbewegingen."
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Het totale gewicht van de voorraadbewegingen."
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr "Voorraad configuratie afmetingen"
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr "Afmetingen"
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr "Volume"
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr "Gewicht"
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr "Afmetingen"
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr "Afmetingen"
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr "Afmetingen"
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr "Afmetingen"
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr "Afmetingen"
diff --git a/modules/stock_shipment_measurements/locale/pl.po b/modules/stock_shipment_measurements/locale/pl.po
new file mode 100644
index 0000000000..05ab686bf9
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/pl.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr ""
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr ""
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr ""
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr ""
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr ""
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/pt.po b/modules/stock_shipment_measurements/locale/pt.po
new file mode 100644
index 0000000000..07e526ea5d
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/pt.po
@@ -0,0 +1,285 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr "Volume Interno"
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr "Peso Interno"
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr "Peso Adicional"
+
+#, fuzzy
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr "Peso Adicional"
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr "Volume Total"
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr "Peso Total"
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr "Volume"
+
+#, fuzzy
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volume"
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr "Peso"
+
+#, fuzzy
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr "Peso"
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr "Volume"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volume"
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr "Peso"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr "Peso"
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr "Volume"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volume"
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr "Peso"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "Peso"
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr "Volume"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volume"
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr "Peso"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr "Peso"
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr "Volume"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volume"
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr "Peso"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "Peso"
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr "O volume do produto movido em litros."
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr "O peso do produto movido em kg."
+
+#, fuzzy
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr "O peso a adicionar aos pacotes em kg."
+
+#, fuzzy
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr "O volume total dos pacotes em litros."
+
+#, fuzzy
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr "O peso total dos pacotes em kg."
+
+#, fuzzy
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr "O volume total dos registros das movimentações em litros."
+
+#, fuzzy
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr "O peso total dos registros das movimentações em kg."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr "O volume total dos registros das movimentações em litros."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr "O peso total dos registros das movimentações em kg."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "O volume total dos pacotes em litros."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "O peso total dos pacotes em kg."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "O volume total dos registros das movimentações em litros."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "O peso total dos registros das movimentações em kg."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "O volume total dos pacotes em litros."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "O peso total dos pacotes em kg."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr "O volume total dos registros das movimentações em litros."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr "O peso total dos registros das movimentações em kg."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "O volume total dos registros das movimentações em litros."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "O peso total dos registros das movimentações em kg."
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr "Volume"
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr "Peso"
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/ro.po b/modules/stock_shipment_measurements/locale/ro.po
new file mode 100644
index 0000000000..05ab686bf9
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/ro.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr ""
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr ""
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr ""
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr ""
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr ""
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/ru.po b/modules/stock_shipment_measurements/locale/ru.po
new file mode 100644
index 0000000000..05ab686bf9
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/ru.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr ""
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr ""
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr ""
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr ""
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr ""
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/sl.po b/modules/stock_shipment_measurements/locale/sl.po
new file mode 100644
index 0000000000..11e6362c96
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/sl.po
@@ -0,0 +1,285 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr "Neto volumen"
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr "Neto teža"
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr "Dodatna teža"
+
+#, fuzzy
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr "Dodatna teža"
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr "Bruto volumen"
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr "Bruto teža"
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr "Volumen"
+
+#, fuzzy
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volumen"
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr "Teža"
+
+#, fuzzy
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr "Teža"
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr "Volumen"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volumen"
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr "Teža"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr "Teža"
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr "Volumen"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volumen"
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr "Teža"
+
+#, fuzzy
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "Teža"
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr "Volumen"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volumen"
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr "Teža"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr "Teža"
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr "Volumen"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr "Volumen"
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr "Teža"
+
+#, fuzzy
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr "Teža"
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr "Volumen premaknjenega izdelka v litrih."
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr "Teža premaknjenega izdelka v kilogramih."
+
+#, fuzzy
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr "Dodatna teža v kilogramih zaradi pakiranja."
+
+#, fuzzy
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr "Skupna prostornina paketov v litrih."
+
+#, fuzzy
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr "Skupna teža paketov v kilogramih."
+
+#, fuzzy
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Skupni volumen v litrih za premike paketa."
+
+#, fuzzy
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Skupna teža v kilogramih za premike paketa."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Skupni volumen v litrih za premike paketa."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Skupna teža v kilogramih za premike paketa."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "Skupna prostornina paketov v litrih."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "Skupna teža paketov v kilogramih."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Skupni volumen v litrih za premike paketa."
+
+#, fuzzy
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Skupna teža v kilogramih za premike paketa."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr "Skupna prostornina paketov v litrih."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr "Skupna teža paketov v kilogramih."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Skupni volumen v litrih za premike paketa."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Skupna teža v kilogramih za premike paketa."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr "Skupni volumen v litrih za premike paketa."
+
+#, fuzzy
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr "Skupna teža v kilogramih za premike paketa."
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr "Volumen"
+
+#, fuzzy
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr "Teža"
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/tr.po b/modules/stock_shipment_measurements/locale/tr.po
new file mode 100644
index 0000000000..05ab686bf9
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/tr.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr ""
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr ""
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr ""
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr ""
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr ""
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/uk.po b/modules/stock_shipment_measurements/locale/uk.po
new file mode 100644
index 0000000000..05ab686bf9
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/uk.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr ""
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr ""
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr ""
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr ""
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr ""
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/locale/zh_CN.po b/modules/stock_shipment_measurements/locale/zh_CN.po
new file mode 100644
index 0000000000..05ab686bf9
--- /dev/null
+++ b/modules/stock_shipment_measurements/locale/zh_CN.po
@@ -0,0 +1,255 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.configuration,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_volume_uom:"
+msgid "Measurement Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.configuration.measurement,measurement_weight_uom:"
+msgid "Measurement Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.move,internal_volume:"
+msgid "Internal Volume"
+msgstr ""
+
+msgctxt "field:stock.move,internal_weight:"
+msgid "Internal Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight:"
+msgid "Additional Weight"
+msgstr ""
+
+msgctxt "field:stock.package,additional_weight_uom:"
+msgid "Additional Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.package,total_volume:"
+msgid "Total Volume"
+msgstr ""
+
+msgctxt "field:stock.package,total_weight:"
+msgid "Total Weight"
+msgstr ""
+
+msgctxt "field:stock.package,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.package,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.package,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.package,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.in.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_volume:"
+msgid "Packages Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,packages_weight:"
+msgid "Packages Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,volume_uom:"
+msgid "Volume Uom"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "field:stock.shipment.out.return,weight_uom:"
+msgid "Weight Uom"
+msgstr ""
+
+msgctxt "help:stock.move,internal_volume:"
+msgid "The volume of the moved product in liter."
+msgstr ""
+
+msgctxt "help:stock.move,internal_weight:"
+msgid "The weight of the moved product in kg."
+msgstr ""
+
+msgctxt "help:stock.package,additional_weight:"
+msgid "The weight to add to the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,total_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.package,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.package,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.in.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_volume:"
+msgid "The total volume of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,packages_weight:"
+msgid "The total weight of the packages."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,volume:"
+msgid "The total volume of the record's moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.out.return,weight:"
+msgid "The total weight of the record's moves."
+msgstr ""
+
+msgctxt "model:stock.configuration.measurement,name:"
+msgid "Stock Configuration Measurement"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Volume"
+msgstr ""
+
+msgctxt "view:stock.configuration:"
+msgid "Weight"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.in:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out.return:"
+msgid "Measurements"
+msgstr ""
+
+msgctxt "view:stock.shipment.out:"
+msgid "Measurements"
+msgstr ""
diff --git a/modules/stock_shipment_measurements/setup.py b/modules/stock_shipment_measurements/setup.py
new file mode 100755
index 0000000000..1405c96ab6
--- /dev/null
+++ b/modules/stock_shipment_measurements/setup.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_shipment_measurements'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = []
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [get_require_version('trytond_stock_package')]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module to add measurements to shipment',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": (
+ 'https://hg.tryton.org/modules/stock_shipment_measurements'),
+ },
+ keywords='tryton stock shipment measurement',
+ package_dir={'trytond.modules.stock_shipment_measurements': '.'},
+ packages=(
+ ['trytond.modules.stock_shipment_measurements']
+ + ['trytond.modules.stock_shipment_measurements.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_shipment_measurements': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_shipment_measurements = trytond.modules.stock_shipment_measurements
+ """,
+ )
diff --git a/modules/stock_shipment_measurements/stock.py b/modules/stock_shipment_measurements/stock.py
new file mode 100644
index 0000000000..fe815e5c2b
--- /dev/null
+++ b/modules/stock_shipment_measurements/stock.py
@@ -0,0 +1,457 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from collections import defaultdict
+from itertools import groupby
+
+from sql.aggregate import Sum
+from sql.operators import Concat
+
+from trytond.model import ModelSQL, fields
+from trytond.modules.company.model import CompanyValueMixin
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Bool, Eval, Id
+from trytond.tools import grouped_slice, reduce_ids
+from trytond.transaction import Transaction
+
+
+class Configuration(metaclass=PoolMeta):
+ __name__ = 'stock.configuration'
+
+ measurement_weight_uom = fields.MultiValue(
+ fields.Many2One(
+ 'product.uom', "Measurement Weight Uom", required=True,
+ domain=[('category', '=', Id('product', 'uom_cat_weight'))]))
+ measurement_volume_uom = fields.MultiValue(
+ fields.Many2One(
+ 'product.uom', "Measurement Volume Uom", required=True,
+ domain=[('category', '=', Id('product', 'uom_cat_volume'))]))
+
+ @classmethod
+ def multivalue_model(cls, field):
+ pool = Pool()
+ if field in {'measurement_weight_uom', 'measurement_volume_uom'}:
+ return pool.get('stock.configuration.measurement')
+ return super().multivalue_model(field)
+
+ @classmethod
+ def default_measurement_weight_uom(cls, **pattern):
+ model = cls.multivalue_model('measurement_weight_uom')
+ return model.default_measurement_weight_uom()
+
+ @classmethod
+ def default_measurement_volume_uom(cls, **pattern):
+ model = cls.multivalue_model('measurement_volume_uom')
+ return model.default_measurement_volume_uom()
+
+
+class ConfigurationMeasurement(ModelSQL, CompanyValueMixin):
+ "Stock Configuration Measurement"
+ __name__ = 'stock.configuration.measurement'
+
+ measurement_weight_uom = fields.Many2One(
+ 'product.uom', "Measurement Weight Uom", required=True,
+ domain=[('category', '=', Id('product', 'uom_cat_weight'))])
+ measurement_volume_uom = fields.Many2One(
+ 'product.uom', "Measurement Volume Uom", required=True,
+ domain=[('category', '=', Id('product', 'uom_cat_volume'))])
+
+ @classmethod
+ def default_measurement_weight_uom(cls):
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ ModelData = pool.get('ir.model.data')
+ return Uom(ModelData.get_id('product', 'uom_kilogram')).id
+
+ @classmethod
+ def default_measurement_volume_uom(cls):
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ ModelData = pool.get('ir.model.data')
+ return Uom(ModelData.get_id('product', 'uom_liter')).id
+
+
+class Move(metaclass=PoolMeta):
+ __name__ = 'stock.move'
+
+ internal_weight = fields.Float(
+ "Internal Weight", readonly=True,
+ help="The weight of the moved product in kg.")
+ internal_volume = fields.Float(
+ "Internal Volume", readonly=True,
+ help="The volume of the moved product in liter.")
+
+ @classmethod
+ def _get_internal_weight(cls, quantity, uom, product):
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ ModelData = pool.get('ir.model.data')
+
+ kg = Uom(ModelData.get_id('product', 'uom_kilogram'))
+
+ # Use first the weight from product_measurements
+ # as it could include some handling weight
+ if product.weight is not None:
+ internal_quantity = cls._get_internal_quantity(
+ quantity, uom, product)
+ return Uom.compute_qty(
+ product.weight_uom, internal_quantity * product.weight, kg,
+ round=False)
+ elif uom.category == kg.category:
+ return Uom.compute_qty(uom, quantity, kg, round=False)
+ else:
+ return None
+
+ @classmethod
+ def _get_internal_volume(cls, quantity, uom, product):
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ ModelData = pool.get('ir.model.data')
+
+ liter = Uom(ModelData.get_id('product', 'uom_liter'))
+
+ # Use first the volume from product_measurements
+ # as it could include some handling volume
+ if product.volume is not None:
+ internal_quantity = cls._get_internal_quantity(
+ quantity, uom, product)
+ return Uom.compute_qty(
+ product.volume_uom, internal_quantity * product.volume, liter,
+ round=False)
+ elif uom.category == liter.category:
+ return Uom.compute_qty(uom, quantity, liter, round=False)
+ else:
+ return None
+
+ @classmethod
+ def create(cls, vlist):
+ pool = Pool()
+ Product = pool.get('product.product')
+ Uom = pool.get('product.uom')
+
+ vlist = [v.copy() for v in vlist]
+ for values in vlist:
+ product = Product(values['product'])
+ uom = Uom(values['uom'])
+ quantity = values['quantity']
+ internal_weight = cls._get_internal_weight(quantity, uom, product)
+ if internal_weight is not None:
+ values['internal_weight'] = internal_weight
+ internal_volume = cls._get_internal_volume(quantity, uom, product)
+ if internal_volume is not None:
+ values['internal_volume'] = internal_volume
+ return super(Move, cls).create(vlist)
+
+ @classmethod
+ def write(cls, *args):
+ super(Move, cls).write(*args)
+
+ to_write = []
+ actions = iter(args)
+ for moves, values in zip(actions, actions):
+ for move in moves:
+ write = {}
+ internal_weight = cls._get_internal_weight(
+ move.quantity, move.uom, move.product)
+ if (internal_weight is not None
+ and internal_weight != move.internal_weight
+ and internal_weight != values.get('internal_weight')):
+ write['internal_weight'] = internal_weight
+ internal_volume = cls._get_internal_volume(
+ move.quantity, move.uom, move.product)
+ if (internal_volume is not None
+ and internal_volume != move.internal_volume
+ and internal_volume != values.get('internal_volume')):
+ write['internal_volume'] = internal_volume
+ if write:
+ to_write.extend(([move], write))
+ if to_write:
+ cls.write(*to_write)
+
+
+class MeasurementsMixin(object):
+ __slots__ = ()
+ weight = fields.Function(
+ fields.Float(
+ "Weight", digits='weight_uom',
+ states={
+ 'invisible': ~Eval('weight'),
+ },
+ help="The total weight of the record's moves."),
+ 'get_measurements', searcher='search_measurements')
+ weight_uom = fields.Function(
+ fields.Many2One('product.uom', "Weight Uom"), 'get_measurements_uom')
+ volume = fields.Function(
+ fields.Float(
+ "Volume", digits='volume_uom',
+ states={
+ 'invisible': ~Eval('volume'),
+ },
+ help="The total volume of the record's moves."),
+ 'get_measurements', searcher='search_measurements')
+ volume_uom = fields.Function(
+ fields.Many2One('product.uom', "Volume Uom"), 'get_measurements_uom')
+
+ @classmethod
+ def get_measurements_uom(cls, shipments, name):
+ pool = Pool()
+ Configuration = pool.get('stock.configuration')
+ configuration = Configuration(1)
+ uoms = {}
+ for company, shipments in groupby(shipments, key=lambda s: s.company):
+ uom = configuration.get_multivalue(
+ 'measurement_%s' % name, company=company.id)
+ for shipment in shipments:
+ uoms[shipment.id] = uom.id
+ return uoms
+
+ @classmethod
+ def get_measurements(cls, shipments, names):
+ pool = Pool()
+ Location = pool.get('stock.location')
+ ModelData = pool.get('ir.model.data')
+ Move = pool.get('stock.move')
+ Uom = pool.get('product.uom')
+
+ kg = Uom(ModelData.get_id('product', 'uom_kilogram'))
+ liter = Uom(ModelData.get_id('product', 'uom_liter'))
+
+ cursor = Transaction().connection.cursor()
+ table = cls.__table__()
+ move = Move.__table__()
+ location = Location.__table__()
+ measurements = defaultdict(lambda: defaultdict(lambda: None))
+
+ query = table.join(
+ move, type_='LEFT',
+ condition=cls._measurements_move_condition(table, move)
+ ).join(
+ location,
+ condition=cls._measurements_location_condition(
+ table, move, location)
+ ).select(
+ table.id,
+ Sum(move.internal_weight),
+ Sum(move.internal_volume),
+ group_by=[table.id])
+
+ id2shipment = {s.id: s for s in shipments}
+ for sub_shipments in grouped_slice(shipments):
+ query.where = reduce_ids(
+ table.id, [s.id for s in sub_shipments])
+ cursor.execute(*query)
+ for id_, weight, volume in cursor:
+ shipment = id2shipment[id_]
+ if 'weight' in names:
+ measurements['weight'][id_] = Uom.compute_qty(
+ kg, weight, shipment.weight_uom)
+ if 'volume' in names:
+ measurements['volume'][id_] = Uom.compute_qty(
+ liter, volume, shipment.volume_uom)
+ return measurements
+
+ @classmethod
+ def search_measurements(cls, name, clause):
+ pool = Pool()
+ Configuration = pool.get('stock.configuration')
+ Location = pool.get('stock.location')
+ ModelData = pool.get('ir.model.data')
+ Move = pool.get('stock.move')
+ Uom = pool.get('product.uom')
+
+ table = cls.__table__()
+ move = Move.__table__()
+ location = Location.__table__()
+ configuration = Configuration(1)
+ uom = configuration.get_multivalue('measurement_%s_uom' % name)
+
+ _, operator, value = clause
+
+ Operator = fields.SQL_OPERATORS[operator]
+ if name == 'weight':
+ measurement = Sum(move.internal_weight)
+ if value is not None:
+ kg = Uom(ModelData.get_id('product', 'uom_kilogram'))
+ value = Uom.compute_qty(uom, value, kg, round=False)
+ else:
+ measurement = Sum(move.internal_volume)
+ if value is not None:
+ liter = Uom(ModelData.get_id('product', 'uom_liter'))
+ value = Uom.compute_qty(uom, value, liter, round=False)
+
+ query = table.join(
+ move, type_='LEFT',
+ condition=cls._measurements_move_condition(table, move)
+ ).join(
+ location,
+ condition=cls._measurements_location_condition(
+ table, move, location)
+ ).select(
+ table.id,
+ group_by=[table.id],
+ having=Operator(measurement, value))
+ return [('id', 'in', query)]
+
+ @classmethod
+ def _measurements_move_condition(cls, table, move):
+ return Concat(cls.__name__ + ',', table.id) == move.shipment
+
+ @classmethod
+ def _measurements_location_condition(cls, table, move, location):
+ raise NotImplementedError
+
+
+class ShipmentIn(MeasurementsMixin, object, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in'
+
+ @classmethod
+ def _measurements_location_condition(cls, shipment, move, location):
+ return (
+ (move.from_location == location.id)
+ & (location.type == 'supplier'))
+
+
+class ShipmentInReturn(MeasurementsMixin, object, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in.return'
+
+ @classmethod
+ def _measurements_location_condition(cls, shipment, move, location):
+ return move.from_location == location.id
+
+
+class ShipmentOut(MeasurementsMixin, object, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out'
+
+ @classmethod
+ def _measurements_location_condition(cls, shipment, move, location):
+ return (
+ (move.to_location == location.id)
+ & (location.type == 'customer'))
+
+ @fields.depends('carrier')
+ def _parcel_weight(self, parcel):
+ pool = Pool()
+ ModelData = pool.get('ir.model.data')
+ Uom = pool.get('product.uom')
+ kg = Uom(ModelData.get_id('product', 'uom_kilogram'))
+ weight = super()._parcel_weight(parcel)
+ if self.carrier:
+ carrier_uom = self.carrier.weight_uom
+ packages = {p for l in parcel for p in l.package_path}
+ for package in packages:
+ if package.additional_weight:
+ weight += Uom.compute_qty(
+ kg, package.additional_weight, carrier_uom,
+ round=False)
+ return weight
+
+
+class ShipmentOutReturn(MeasurementsMixin, object, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out.return'
+
+ @classmethod
+ def _measurements_location_condition(cls, shipment, move, location):
+ return (
+ (move.from_location == location.id)
+ & (location.type == 'customer'))
+
+# TODO ShipmentInternal
+
+
+class Package(MeasurementsMixin, object, metaclass=PoolMeta):
+ __name__ = 'stock.package'
+
+ additional_weight = fields.Float(
+ "Additional Weight", digits='additional_weight_uom',
+ help="The weight to add to the packages.")
+ additional_weight_uom = fields.Many2One(
+ 'product.uom', "Additional Weight Uom",
+ domain=[('category', '=', Id('product', 'uom_cat_weight'))],
+ states={
+ 'required': Bool(Eval('additional_weight')),
+ })
+ total_weight = fields.Function(
+ fields.Float(
+ "Total Weight", digits='weight_uom',
+ states={
+ 'invisible': ~Eval('total_weight'),
+ },
+ help="The total weight of the packages."),
+ 'get_total_measurements')
+ total_volume = fields.Function(
+ fields.Float(
+ "Total Volume", digits='volume_uom',
+ states={
+ 'invisible': ~Eval('total_volume'),
+ },
+ help="The total volume of the packages."),
+ 'get_total_measurements')
+
+ @classmethod
+ def default_additional_weight_uom(cls):
+ pool = Pool()
+ Configuration = pool.get('stock.configuration')
+ configuration = Configuration(1)
+ return configuration.get_multivalue('measurement_weight_uom').id
+
+ @classmethod
+ def _measurements_move_condition(cls, package, move):
+ return package.id == move.package
+
+ @classmethod
+ def _measurements_location_condition(cls, package, move, location):
+ return move.to_location == location.id
+
+ def get_total_measurements(self, name, round=True):
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ field = name[len('total_'):]
+
+ if name == 'total_volume' and self.packaging_volume is not None:
+ return Uom.compute_qty(
+ self.packaging_volume_uom, self.packaging_volume,
+ self.volume_uom, round=round)
+
+ measurement = (
+ (getattr(self, field) or 0)
+ + sum(p.get_total_measurements(name, round=False)
+ for p in self.children))
+ if name == 'total_weight':
+ if self.additional_weight:
+ measurement += Uom.compute_qty(
+ self.additional_weight_uom, self.additional_weight,
+ self.weight_uom, round=False)
+ if self.packaging_weight:
+ measurement += Uom.compute_qty(
+ self.packaging_weight_uom, self.packaging_weight,
+ self.weight_uom, round=False)
+ if round:
+ return getattr(self, field + '_uom').round(measurement)
+ else:
+ return measurement
+
+
+class MeasurementsPackageMixin:
+ __slots__ = ()
+
+ packages_weight = fields.Function(
+ fields.Float("Packages Weight", digits='weight_uom',
+ help="The total weight of the packages."),
+ 'get_packages_measurements')
+ packages_volume = fields.Function(
+ fields.Float("Packages Volume", digits='volume_uom',
+ help="The total volume of the packages."),
+ 'get_packages_measurements')
+
+ def get_packages_measurements(self, name):
+ name = name[len('packages_'):]
+ uom = getattr(self, name + '_uom')
+ return uom.round(
+ sum(getattr(p, 'total_' + name)for p in self.root_packages))
+
+
+class ShipmentOutPackage(MeasurementsPackageMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out'
+
+
+class ShipmentInReturnPackage(MeasurementsPackageMixin, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in.return'
diff --git a/modules/stock_shipment_measurements/stock.xml b/modules/stock_shipment_measurements/stock.xml
new file mode 100644
index 0000000000..6894c7a949
--- /dev/null
+++ b/modules/stock_shipment_measurements/stock.xml
@@ -0,0 +1,103 @@
+
+
+
+
+
+ stock.configuration
+
+ configuration_form
+
+
+
+ stock.move
+
+ stock_move_form
+
+
+
+ stock.shipment.in
+
+ shipment_list
+
+
+ stock.shipment.in
+
+ shipment_form
+
+
+ stock.shipment.in.return
+
+ shipment_list
+
+
+ stock.shipment.in.return
+
+ shipment_form
+
+
+ stock.shipment.out
+
+ shipment_list
+
+
+ stock.shipment.out
+
+ shipment_form
+
+
+ stock.shipment.out.return
+
+ shipment_list
+
+
+ stock.shipment.out.return
+
+ shipment_form
+
+
+
+
+
+ stock.package
+
+ package_tree
+
+
+ stock.package
+
+ package_list
+
+
+ stock.package
+
+ package_form
+
+
+
+ stock.shipment.in.return
+
+
+ shipment_list_package
+
+
+ stock.shipment.in.return
+
+
+ shipment_form_package
+
+
+
+ stock.shipment.out
+
+
+ shipment_list_package
+
+
+ stock.shipment.out
+
+
+ shipment_form_package
+
+
+
diff --git a/modules/stock_shipment_measurements/tests/__init__.py b/modules/stock_shipment_measurements/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_shipment_measurements/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_shipment_measurements/tests/test_module.py b/modules/stock_shipment_measurements/tests/test_module.py
new file mode 100644
index 0000000000..4b264e9332
--- /dev/null
+++ b/modules/stock_shipment_measurements/tests/test_module.py
@@ -0,0 +1,223 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from decimal import Decimal
+
+from trytond.modules.company.tests import (
+ CompanyTestMixin, create_company, set_company)
+from trytond.pool import Pool
+from trytond.tests.test_tryton import (
+ ModuleTestCase, activate_module, with_transaction)
+
+
+class StockShipmentMeasurementsTestCase(CompanyTestMixin, ModuleTestCase):
+ 'Test Stock Shipment Measurements module'
+ module = 'stock_shipment_measurements'
+ extras = ['stock_package']
+ longMessage = True
+
+ @classmethod
+ def setUpClass(cls):
+ super(StockShipmentMeasurementsTestCase, cls).setUpClass()
+ activate_module('stock_package')
+
+ @with_transaction()
+ def test_move_internal_measurements(self):
+ "Test move internal measurements"
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ Template = pool.get('product.template')
+ Product = pool.get('product.product')
+ Location = pool.get('stock.location')
+ Move = pool.get('stock.move')
+
+ kg, = Uom.search([('name', '=', 'Kilogram')])
+ g, = Uom.search([('name', '=', 'Gram')])
+ liter, = Uom.search([('name', '=', 'Liter')])
+ supplier, = Location.search([('code', '=', 'SUP')])
+ storage, = Location.search([('code', '=', 'STO')])
+ company = create_company()
+ currency = company.currency
+
+ template, = Template.create([{
+ 'name': "Test internal measurements",
+ 'type': 'goods',
+ 'default_uom': kg,
+ }])
+ product, = Product.create([{
+ 'template': template.id,
+ }])
+
+ # without any measurements
+ with set_company(company):
+ move, = Move.create([{
+ 'product': product,
+ 'uom': g,
+ 'quantity': 200,
+ 'from_location': supplier,
+ 'to_location': storage,
+ 'company': company,
+ 'unit_price': Decimal(1),
+ 'currency': currency,
+ }])
+ self.assertEqual(move.internal_weight, 0.2)
+ self.assertEqual(move.internal_volume, None)
+
+ Move.write([move], {'quantity': 100})
+ self.assertEqual(move.internal_weight, 0.1)
+ self.assertEqual(move.internal_volume, None)
+
+ template.weight = 1.1
+ template.weight_uom = kg
+ template.save()
+
+ # with weight measurements
+ with set_company(company):
+ move, = Move.create([{
+ 'product': product,
+ 'uom': g,
+ 'quantity': 300,
+ 'from_location': supplier,
+ 'to_location': storage,
+ 'company': company,
+ 'unit_price': Decimal(1),
+ 'currency': currency,
+ }])
+ self.assertEqual(move.internal_weight, 0.33)
+ self.assertEqual(move.internal_volume, None)
+
+ Move.write([move], {'quantity': 500})
+ self.assertEqual(move.internal_weight, 0.55)
+ self.assertEqual(move.internal_volume, None)
+
+ template.volume = 2
+ template.volume_uom = liter
+ template.save()
+
+ # with weight and volume measurements
+ with set_company(company):
+ move, = Move.create([{
+ 'product': product,
+ 'uom': g,
+ 'quantity': 500,
+ 'from_location': supplier,
+ 'to_location': storage,
+ 'company': company,
+ 'unit_price': Decimal(1),
+ 'currency': currency,
+ }])
+ self.assertEqual(move.internal_weight, 0.55)
+ self.assertEqual(move.internal_volume, 1)
+
+ Move.write([move], {'quantity': 600})
+ self.assertEqual(move.internal_weight, 0.66)
+ self.assertEqual(move.internal_volume, 1.2)
+
+ @with_transaction()
+ def test_shipment_out_measurements(self):
+ "Test shipment out measurements"
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ Template = pool.get('product.template')
+ Product = pool.get('product.product')
+ Location = pool.get('stock.location')
+ Move = pool.get('stock.move')
+ Shipment = pool.get('stock.shipment.out')
+ Package = pool.get('stock.package')
+ PackageType = pool.get('stock.package.type')
+ Party = pool.get('party.party')
+
+ kg, = Uom.search([('name', '=', 'Kilogram')])
+ liter, = Uom.search([('name', '=', 'Liter')])
+ customer, = Location.search([('code', '=', 'CUS')])
+ storage, = Location.search([('code', '=', 'STO')])
+ party = Party(name='Customer')
+ party.addresses = [{}]
+ party.save()
+ company = create_company()
+ currency = company.currency
+ package_type = PackageType(name="Type")
+ package_type.save()
+
+ template, = Template.create([{
+ 'name': "Test measurements",
+ 'type': 'goods',
+ 'default_uom': kg,
+ 'volume': 0.2,
+ 'volume_uom': liter,
+ }])
+ product, = Product.create([{
+ 'template': template.id,
+ }])
+
+ with set_company(company):
+ shipment = Shipment()
+ shipment.customer = party
+ shipment.delivery_address, = party.addresses
+ shipment.save()
+
+ # without moves
+ self.assertEqual(shipment.weight, None)
+ self.assertEqual(shipment.volume, None)
+
+ shipment.moves = [Move(
+ product=product,
+ uom=kg,
+ quantity=10,
+ from_location=storage,
+ to_location=customer,
+ company=company,
+ unit_price=Decimal(1),
+ currency=currency,
+ )]
+ shipment.save()
+
+ # without inventory moves
+ self.assertEqual(shipment.weight, 10)
+ self.assertEqual(shipment.volume, 2)
+
+ Shipment.wait([shipment])
+
+ # with inventory moves
+ self.assertEqual(shipment.weight, 10)
+ self.assertEqual(shipment.volume, 2)
+
+ for clause, result in [
+ ([('weight', '=', 10)], [shipment]),
+ ([('weight', '=', 5)], []),
+ ([('volume', '=', 2)], [shipment]),
+ ([('volume', '=', 3)], []),
+ ]:
+ msg = 'clause: %s' % clause
+ self.assertEqual(Shipment.search(clause), result, msg=msg)
+
+ # Add packages
+ package_root = Package()
+ package_root.type = package_type
+ package_root.shipment = shipment
+ package_root.additional_weight = 1
+ package_root.packaging_volume = 3
+ package_root.packaging_volume_uom = liter
+ package_root.save()
+
+ package = Package()
+ package.type = package_type
+ package.shipment = shipment
+ package.moves = shipment.moves
+ package.parent = package_root
+ package.save()
+
+ self.assertEqual(package_root.weight, None)
+ self.assertEqual(package_root.volume, None)
+
+ self.assertEqual(package.weight, 10)
+ self.assertEqual(package.volume, 2)
+
+ self.assertEqual(package_root.total_weight, 11)
+ self.assertEqual(package_root.total_volume, 3)
+
+ self.assertEqual(package.total_weight, 10)
+ self.assertEqual(package.total_volume, 2)
+
+
+del ModuleTestCase
diff --git a/modules/stock_shipment_measurements/tox.ini b/modules/stock_shipment_measurements/tox.ini
new file mode 100644
index 0000000000..bff1ab828c
--- /dev/null
+++ b/modules/stock_shipment_measurements/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_shipment_measurements/* -m unittest discover -s tests
+ coverage report --include=./**/stock_shipment_measurements/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_shipment_measurements/tryton.cfg b/modules/stock_shipment_measurements/tryton.cfg
new file mode 100644
index 0000000000..43dc58e0d4
--- /dev/null
+++ b/modules/stock_shipment_measurements/tryton.cfg
@@ -0,0 +1,13 @@
+[tryton]
+version=6.7.0
+depends:
+ company
+ ir
+ product
+ product_measurements
+ stock
+extras_depend:
+ carrier_weight
+ stock_package
+xml:
+ stock.xml
diff --git a/modules/stock_shipment_measurements/view/configuration_form.xml b/modules/stock_shipment_measurements/view/configuration_form.xml
new file mode 100644
index 0000000000..b15be3b412
--- /dev/null
+++ b/modules/stock_shipment_measurements/view/configuration_form.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_shipment_measurements/view/package_form.xml b/modules/stock_shipment_measurements/view/package_form.xml
new file mode 100644
index 0000000000..116e6b9ddd
--- /dev/null
+++ b/modules/stock_shipment_measurements/view/package_form.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_shipment_measurements/view/package_list.xml b/modules/stock_shipment_measurements/view/package_list.xml
new file mode 100644
index 0000000000..4479f66b9f
--- /dev/null
+++ b/modules/stock_shipment_measurements/view/package_list.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_shipment_measurements/view/package_tree.xml b/modules/stock_shipment_measurements/view/package_tree.xml
new file mode 100644
index 0000000000..ca5557b707
--- /dev/null
+++ b/modules/stock_shipment_measurements/view/package_tree.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_shipment_measurements/view/shipment_form.xml b/modules/stock_shipment_measurements/view/shipment_form.xml
new file mode 100644
index 0000000000..26a6c4468c
--- /dev/null
+++ b/modules/stock_shipment_measurements/view/shipment_form.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_shipment_measurements/view/shipment_form_package.xml b/modules/stock_shipment_measurements/view/shipment_form_package.xml
new file mode 100644
index 0000000000..72d036d52d
--- /dev/null
+++ b/modules/stock_shipment_measurements/view/shipment_form_package.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_shipment_measurements/view/shipment_list.xml b/modules/stock_shipment_measurements/view/shipment_list.xml
new file mode 100644
index 0000000000..2ea6ce5e27
--- /dev/null
+++ b/modules/stock_shipment_measurements/view/shipment_list.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_shipment_measurements/view/shipment_list_package.xml b/modules/stock_shipment_measurements/view/shipment_list_package.xml
new file mode 100644
index 0000000000..e1e7820e61
--- /dev/null
+++ b/modules/stock_shipment_measurements/view/shipment_list_package.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_shipment_measurements/view/stock_move_form.xml b/modules/stock_shipment_measurements/view/stock_move_form.xml
new file mode 100644
index 0000000000..38abeda9bd
--- /dev/null
+++ b/modules/stock_shipment_measurements/view/stock_move_form.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_split/.drone.yml b/modules/stock_split/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_split/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_split/.flake8 b/modules/stock_split/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_split/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_split/.isort.cfg b/modules/stock_split/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_split/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_split/CHANGELOG b/modules/stock_split/CHANGELOG
new file mode 100644
index 0000000000..8e41608d08
--- /dev/null
+++ b/modules/stock_split/CHANGELOG
@@ -0,0 +1,73 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+* Add shipment split
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+
+Version 4.2.0 - 2016-11-28
+* Bug fixes (see mercurial logs for details)
+
+Version 4.0.0 - 2016-05-02
+* Bug fixes (see mercurial logs for details)
+* Add Python3 support
+
+Version 3.8.0 - 2015-11-02
+* Bug fixes (see mercurial logs for details)
+
+Version 3.6.0 - 2015-04-20
+* Bug fixes (see mercurial logs for details)
+* Add support for PyPy
+
+Version 3.4.0 - 2014-10-20
+* Bug fixes (see mercurial logs for details)
+
+Version 3.2.0 - 2014-04-21
+* Bug fixes (see mercurial logs for details)
+
+Version 3.0.0 - 2013-10-21
+* Bug fixes (see mercurial logs for details)
+
+Version 2.8.0 - 2013-04-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.6.0 - 2012-10-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.4.0 - 2012-07-31
+* Initial release
diff --git a/modules/stock_split/COPYRIGHT b/modules/stock_split/COPYRIGHT
new file mode 100644
index 0000000000..03f4719f79
--- /dev/null
+++ b/modules/stock_split/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2012-2022 Cédric Krier.
+Copyright (C) 2012-2022 B2CK SPRL.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_split/LICENSE b/modules/stock_split/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_split/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_split/MANIFEST.in b/modules/stock_split/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_split/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_split/README.rst b/modules/stock_split/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_split/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_split/__init__.py b/modules/stock_split/__init__.py
new file mode 100644
index 0000000000..a41283d46d
--- /dev/null
+++ b/modules/stock_split/__init__.py
@@ -0,0 +1,21 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import stock
+
+
+def register():
+ Pool.register(
+ stock.Move,
+ stock.SplitMoveStart,
+ stock.ShipmentInReturn,
+ stock.ShipmentOut,
+ stock.ShipmentInternal,
+ stock.SplitShipmentStart,
+ module='stock_split', type_='model')
+ Pool.register(
+ stock.SplitMove,
+ stock.SplitShipment,
+ module='stock_split', type_='wizard')
diff --git a/modules/stock_split/doc/index.rst b/modules/stock_split/doc/index.rst
new file mode 100644
index 0000000000..7b4647aff3
--- /dev/null
+++ b/modules/stock_split/doc/index.rst
@@ -0,0 +1,11 @@
+Stock Split Module
+##################
+
+The Stock Split module adds on the stock move a wizard that allows to split them.
+The move is split into moves of *Quantity*. If *Counts* is set, it will be
+split only this number of times. On occasion there can be a move with the
+remaining quantity.
+
+It also adds on *Customer*, *Supplier Return* and *Internal* shipments a wizard
+that allows to split them. The selected moves of the shipment are shifted to a
+new copy of the shipment.
diff --git a/modules/stock_split/icons/LICENSE b/modules/stock_split/icons/LICENSE
new file mode 100644
index 0000000000..7a4a3ea242
--- /dev/null
+++ b/modules/stock_split/icons/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git a/modules/stock_split/icons/tryton-stock-split.svg b/modules/stock_split/icons/tryton-stock-split.svg
new file mode 100644
index 0000000000..d64516e11e
--- /dev/null
+++ b/modules/stock_split/icons/tryton-stock-split.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/modules/stock_split/locale/bg.po b/modules/stock_split/locale/bg.po
new file mode 100644
index 0000000000..4cc46365dc
--- /dev/null
+++ b/modules/stock_split/locale/bg.po
@@ -0,0 +1,101 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr "Количество"
+
+#, fuzzy
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr "Мерни единици"
+
+#, fuzzy
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "Категория мер. ед."
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Split Move"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+#, fuzzy
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Split Move"
+
+#, fuzzy
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+#, fuzzy
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+#, fuzzy
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "Отказване"
+
+#, fuzzy
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Split"
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "Отказване"
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Split"
diff --git a/modules/stock_split/locale/ca.po b/modules/stock_split/locale/ca.po
new file mode 100644
index 0000000000..e60d2d823c
--- /dev/null
+++ b/modules/stock_split/locale/ca.po
@@ -0,0 +1,91 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr "Número"
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr "Quantitat"
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr "UdM"
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "Categoria de la UdM"
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr "Moviments del domini"
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr "Moviments"
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr "El número màxim de moviments."
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr "Els moviments seleccionats s'enviaran en un albarà nou."
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Divideix moviments"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Divideix albarà"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Divideix"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Divideix"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Divideix"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Divideix"
+
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Divisió de moviments"
+
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Divideix albarà"
+
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Divideix"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr "Trieu els moviments a enviar en un albarà nou:"
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "Cancel·la"
+
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Divideix"
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "Cancel·la"
+
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Divideix"
diff --git a/modules/stock_split/locale/cs.po b/modules/stock_split/locale/cs.po
new file mode 100644
index 0000000000..77fe7ac737
--- /dev/null
+++ b/modules/stock_split/locale/cs.po
@@ -0,0 +1,96 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Split Move"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+#, fuzzy
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Split Move"
+
+#, fuzzy
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+#, fuzzy
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr ""
+
+#, fuzzy
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr ""
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Split"
diff --git a/modules/stock_split/locale/de.po b/modules/stock_split/locale/de.po
new file mode 100644
index 0000000000..cd9d06b160
--- /dev/null
+++ b/modules/stock_split/locale/de.po
@@ -0,0 +1,94 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr "Anzahl"
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr "Menge"
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr "Einheit"
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "Maßeinheitenkategorie"
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr "Wertebereich Warenbewegungen (Domain)"
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr "Warenbewegungen"
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr "Maximale Anzahl von Warenbewegungen."
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+"Die gewählten Warenbewegungen werden in die neue Lieferung übernommen."
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Warenbewegung aufteilen"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Lieferung aufteilen"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Aufteilen"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Aufteilen"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Aufteilen"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Aufteilen"
+
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Warenbewegung Aufteilung"
+
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Lieferung aufteilen"
+
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Aufteilen"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+"Auswahl der Warenbewegungen, die in die neue Lieferung übernommen werden "
+"sollen:"
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "Abbrechen"
+
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Aufteilen"
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "Abbrechen"
+
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Aufteilen"
diff --git a/modules/stock_split/locale/es.po b/modules/stock_split/locale/es.po
new file mode 100644
index 0000000000..6a512b86dc
--- /dev/null
+++ b/modules/stock_split/locale/es.po
@@ -0,0 +1,91 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr "Contador"
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr "Cantidad"
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr "UdM"
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "Categoría UdM"
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr "Movimientos del dominio"
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr "Movimientos"
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr "El número límite de movimientos."
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr "Los movimientos seleccionados se enviarán en un albarán nuevo."
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Dividir movimiento"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Dividir albarán"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Dividir"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Dividir"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Dividir"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Dividir"
+
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Dividir movimiento"
+
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Dividir albarán"
+
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Dividir"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr "Selecciona los movimientos a enviar en un albarán nuevo:"
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Dividir"
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Dividir"
diff --git a/modules/stock_split/locale/es_419.po b/modules/stock_split/locale/es_419.po
new file mode 100644
index 0000000000..909ac716af
--- /dev/null
+++ b/modules/stock_split/locale/es_419.po
@@ -0,0 +1,91 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "Categoría de UdM"
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr ""
+
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr ""
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr ""
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr ""
diff --git a/modules/stock_split/locale/et.po b/modules/stock_split/locale/et.po
new file mode 100644
index 0000000000..5b1c1b80b2
--- /dev/null
+++ b/modules/stock_split/locale/et.po
@@ -0,0 +1,91 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr "Loendused"
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr "Kogus"
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr "Mõõtühik"
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "Mõõtühiku kategooria"
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr "Liikumised"
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Jaga liikumine"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Jaga lähetus"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Jaga"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Jaga"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Jaga"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Jaga"
+
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Jaga liikumine"
+
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Jaga lähetus"
+
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Jaga"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "Tühista"
+
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Jaga"
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "Tühista"
+
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Jaga"
diff --git a/modules/stock_split/locale/fa.po b/modules/stock_split/locale/fa.po
new file mode 100644
index 0000000000..918208323c
--- /dev/null
+++ b/modules/stock_split/locale/fa.po
@@ -0,0 +1,93 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr "شمارش"
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr "مقدار/تعداد"
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr "واحد اندازی گیری"
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "دسته بندی واحد اندازه گیری"
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr "دامنه جابجایی ها"
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr "جابجایی ها"
+
+#, fuzzy
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr "تعداد محدود جابجایی ها"
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr "جابجایی های انتخاب شده در محموله جدید ارسال خواهند شد."
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "جداسازی جابجایی"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "جداسازی محموله"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "جداسازی جابجایی"
+
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "جداسازی محموله"
+
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "جداسازی"
+
+#, fuzzy
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr "انتخاب جابجایی برای ارسال در محموله جدید"
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "انصراف"
+
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "جداسازی"
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "انصراف"
+
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "جداسازی"
diff --git a/modules/stock_split/locale/fi.po b/modules/stock_split/locale/fi.po
new file mode 100644
index 0000000000..77fe7ac737
--- /dev/null
+++ b/modules/stock_split/locale/fi.po
@@ -0,0 +1,96 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Split Move"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+#, fuzzy
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Split Move"
+
+#, fuzzy
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+#, fuzzy
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr ""
+
+#, fuzzy
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr ""
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Split"
diff --git a/modules/stock_split/locale/fr.po b/modules/stock_split/locale/fr.po
new file mode 100644
index 0000000000..58b2cdc4ca
--- /dev/null
+++ b/modules/stock_split/locale/fr.po
@@ -0,0 +1,92 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr "Décompte"
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr "Quantité"
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr "Unité de mesure"
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "Catégorie d'unité de mesure"
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr "Domaine des mouvements"
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr "Mouvements"
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr "Le nombre limite de mouvements."
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+"Les mouvements sélectionnés seront envoyés sur la nouvelle expédition."
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Diviser le mouvement"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Diviser l'expédition"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Diviser"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Diviser"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Diviser"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Diviser"
+
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Diviser le mouvement"
+
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Diviser l'expédition"
+
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Diviser"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr "Choisir les mouvements à envoyer sur la nouvelle expédition :"
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "Annuler"
+
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Diviser"
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "Annuler"
+
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Diviser"
diff --git a/modules/stock_split/locale/hu.po b/modules/stock_split/locale/hu.po
new file mode 100644
index 0000000000..b0fc45b65f
--- /dev/null
+++ b/modules/stock_split/locale/hu.po
@@ -0,0 +1,96 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr "Mennyiség"
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr "Mennyiség"
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr "Egység"
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "Egység kategória"
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr ""
+
+#, fuzzy
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr "Raktár mozgatás max. mennyisége"
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Split Move"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Raktár mozgatás beosztása"
+
+#, fuzzy
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Beosztás"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "Mégse"
+
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Beosztás"
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "Mégse"
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Beosztás"
diff --git a/modules/stock_split/locale/id.po b/modules/stock_split/locale/id.po
new file mode 100644
index 0000000000..29f0d91e1d
--- /dev/null
+++ b/modules/stock_split/locale/id.po
@@ -0,0 +1,91 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr "Perpindahan"
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr ""
+
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr ""
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "Batal"
+
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr ""
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "Batal"
+
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr ""
diff --git a/modules/stock_split/locale/it.po b/modules/stock_split/locale/it.po
new file mode 100644
index 0000000000..4690dfa6eb
--- /dev/null
+++ b/modules/stock_split/locale/it.po
@@ -0,0 +1,96 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr "Conteggi"
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr "Quantità"
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr "UdM"
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "Categoria UdM"
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr "Dominio dei movimenti"
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr "Movimenti"
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Split Move"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+#, fuzzy
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Split Move"
+
+#, fuzzy
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+#, fuzzy
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "Annulla"
+
+#, fuzzy
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "Annulla"
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Split"
diff --git a/modules/stock_split/locale/lo.po b/modules/stock_split/locale/lo.po
new file mode 100644
index 0000000000..6f12ddfe85
--- /dev/null
+++ b/modules/stock_split/locale/lo.po
@@ -0,0 +1,96 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr "ນັບ"
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr "ຈຳນວນ"
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr "ຫົວໜ່ວຍ"
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "ໝວດຫົວໜ່ວຍ"
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr ""
+
+#, fuzzy
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr "ຕົວເລກຈຳກັດຂອງການເຄື່ອນຍ້າຍ"
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Split Move"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "ແຍກການເຄື່ອນຍ້າຍ"
+
+#, fuzzy
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "ແຍກ"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "ຍົກເລີກ"
+
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "ແຍກ"
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "ຍົກເລີກ"
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "ແຍກ"
diff --git a/modules/stock_split/locale/lt.po b/modules/stock_split/locale/lt.po
new file mode 100644
index 0000000000..77fe7ac737
--- /dev/null
+++ b/modules/stock_split/locale/lt.po
@@ -0,0 +1,96 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Split Move"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+#, fuzzy
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Split Move"
+
+#, fuzzy
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+#, fuzzy
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr ""
+
+#, fuzzy
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr ""
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Split"
diff --git a/modules/stock_split/locale/nl.po b/modules/stock_split/locale/nl.po
new file mode 100644
index 0000000000..1cfbe505c8
--- /dev/null
+++ b/modules/stock_split/locale/nl.po
@@ -0,0 +1,91 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr "tellingen"
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr "Hoeveelheid"
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr "maateenheid"
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "maateenheid categorie"
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr "Mutaties domein"
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr "Mutaties"
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr "maximum aantal bewegingen."
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr "De geselecteerde bewegingen worden verzonden in de nieuwe zending."
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Split de beweging"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Zending splitsen"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "opsplitsen"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "opsplitsen"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "opsplitsen"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "opsplitsen"
+
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Split de beweging"
+
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Zending splitsen"
+
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "opsplitsen"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr "Kies beweging om nieuwe zending te verzenden:"
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "Annuleren"
+
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "opsplitsen"
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "Annuleren"
+
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "opsplitsen"
diff --git a/modules/stock_split/locale/pl.po b/modules/stock_split/locale/pl.po
new file mode 100644
index 0000000000..701628772c
--- /dev/null
+++ b/modules/stock_split/locale/pl.po
@@ -0,0 +1,97 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr "Ilość"
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr "Jm"
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "Kategoria jm"
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr "Ruchy"
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Split Move"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+#, fuzzy
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Split Move"
+
+#, fuzzy
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+#, fuzzy
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#, fuzzy
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Split"
diff --git a/modules/stock_split/locale/pt.po b/modules/stock_split/locale/pt.po
new file mode 100644
index 0000000000..bad3ffa0f0
--- /dev/null
+++ b/modules/stock_split/locale/pt.po
@@ -0,0 +1,95 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr "Contador"
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr "Quantidade"
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr "UDM"
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "Categoria da UDM"
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr "Domínio de Movimentações"
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr "Movimentos"
+
+#, fuzzy
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr "O número limite de movimentações."
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr "As movimentações selecionadas serão enviadas na próxima remessa."
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Split Move"
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Dividir movimento"
+
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Dividir Remessa"
+
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Dividir"
+
+#, fuzzy
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr "Escolher movimentações para enviar na nova remessa"
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Dividir"
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Dividir"
diff --git a/modules/stock_split/locale/ro.po b/modules/stock_split/locale/ro.po
new file mode 100644
index 0000000000..3dde0241d0
--- /dev/null
+++ b/modules/stock_split/locale/ro.po
@@ -0,0 +1,91 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr ""
+
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr ""
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr ""
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr ""
diff --git a/modules/stock_split/locale/ru.po b/modules/stock_split/locale/ru.po
new file mode 100644
index 0000000000..e083304bc9
--- /dev/null
+++ b/modules/stock_split/locale/ru.po
@@ -0,0 +1,101 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr "Кол-во"
+
+#, fuzzy
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr "Ед.изм."
+
+#, fuzzy
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "Категория ед. измерения"
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Split Move"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+#, fuzzy
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Split Move"
+
+#, fuzzy
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+#, fuzzy
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+#, fuzzy
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "Отменить"
+
+#, fuzzy
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Split"
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "Отменить"
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Split"
diff --git a/modules/stock_split/locale/sl.po b/modules/stock_split/locale/sl.po
new file mode 100644
index 0000000000..00ce05cd6f
--- /dev/null
+++ b/modules/stock_split/locale/sl.po
@@ -0,0 +1,96 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr "Število"
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr "Količina"
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr "ME"
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr "Kategorija ME"
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr ""
+
+#, fuzzy
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr "Omejitev števila prenosov"
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Split Move"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Delitev prometa"
+
+#, fuzzy
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Delitev"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "Prekliči"
+
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Delitev"
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "Prekliči"
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Delitev"
diff --git a/modules/stock_split/locale/tr.po b/modules/stock_split/locale/tr.po
new file mode 100644
index 0000000000..77fe7ac737
--- /dev/null
+++ b/modules/stock_split/locale/tr.po
@@ -0,0 +1,96 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Split Move"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+#, fuzzy
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Split Move"
+
+#, fuzzy
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+#, fuzzy
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr ""
+
+#, fuzzy
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr ""
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Split"
diff --git a/modules/stock_split/locale/uk.po b/modules/stock_split/locale/uk.po
new file mode 100644
index 0000000000..3dde0241d0
--- /dev/null
+++ b/modules/stock_split/locale/uk.po
@@ -0,0 +1,91 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr ""
+
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr ""
+
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr ""
+
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr ""
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr ""
+
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr ""
diff --git a/modules/stock_split/locale/zh_CN.po b/modules/stock_split/locale/zh_CN.po
new file mode 100644
index 0000000000..ac3a2b28d6
--- /dev/null
+++ b/modules/stock_split/locale/zh_CN.po
@@ -0,0 +1,98 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:stock.move.split.start,count:"
+msgid "Counts"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,quantity:"
+msgid "Quantity"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom:"
+msgid "Uom"
+msgstr ""
+
+msgctxt "field:stock.move.split.start,uom_category:"
+msgid "Uom Category"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,domain_moves:"
+msgid "Domain Moves"
+msgstr ""
+
+msgctxt "field:stock.shipment.split.start,moves:"
+msgid "Moves"
+msgstr ""
+
+msgctxt "help:stock.move.split.start,count:"
+msgid "The limit number of moves."
+msgstr ""
+
+msgctxt "help:stock.shipment.split.start,moves:"
+msgid "The selected moves will be sent in the new shipment."
+msgstr ""
+
+msgctxt "model:ir.action,name:wizard_split_move"
+msgid "Split Move"
+msgstr "Split Move"
+
+msgctxt "model:ir.action,name:wizard_split_shipment"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+msgctxt "model:ir.model.button,string:move_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_in_return_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_internal_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "model:ir.model.button,string:shipment_out_split_wizard_button"
+msgid "Split"
+msgstr "Split"
+
+#, fuzzy
+msgctxt "model:stock.move.split.start,name:"
+msgid "Split Move"
+msgstr "Split Move"
+
+#, fuzzy
+msgctxt "model:stock.shipment.split.start,name:"
+msgid "Split Shipment"
+msgstr "Split Shipment"
+
+#, fuzzy
+msgctxt "view:stock.move:"
+msgid "Split"
+msgstr "Split"
+
+msgctxt "view:stock.shipment.split.start:"
+msgid "Choose move to send in new shipment:"
+msgstr ""
+
+#, fuzzy
+msgctxt "wizard_button:stock.move.split,start,end:"
+msgid "Cancel"
+msgstr "取消"
+
+#, fuzzy
+msgctxt "wizard_button:stock.move.split,start,split:"
+msgid "Split"
+msgstr "Split"
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,end:"
+msgid "Cancel"
+msgstr "取消"
+
+#, fuzzy
+msgctxt "wizard_button:stock.shipment.split,start,split:"
+msgid "Split"
+msgstr "Split"
diff --git a/modules/stock_split/setup.py b/modules/stock_split/setup.py
new file mode 100755
index 0000000000..070cff72c2
--- /dev/null
+++ b/modules/stock_split/setup.py
@@ -0,0 +1,151 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_split'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = []
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [get_require_version('proteus')]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module to split stock move',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_split',
+ },
+ keywords='tryton stock split',
+ package_dir={'trytond.modules.stock_split': '.'},
+ packages=(
+ ['trytond.modules.stock_split']
+ + ['trytond.modules.stock_split.%s' % p for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_split': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'Intended Audience :: Manufacturing',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_split = trytond.modules.stock_split
+ """,
+ )
diff --git a/modules/stock_split/stock.py b/modules/stock_split/stock.py
new file mode 100644
index 0000000000..d6c655ce3f
--- /dev/null
+++ b/modules/stock_split/stock.py
@@ -0,0 +1,197 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.model import ModelView, fields
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Eval
+from trytond.transaction import Transaction
+from trytond.wizard import Button, StateTransition, StateView, Wizard
+
+
+class Move(metaclass=PoolMeta):
+ __name__ = 'stock.move'
+
+ @classmethod
+ def __setup__(cls):
+ super(Move, cls).__setup__()
+ cls._buttons.update({
+ 'split_wizard': {
+ 'readonly': ~Eval('state').in_(['draft', 'assigned']),
+ 'depends': ['state'],
+ },
+ })
+
+ @classmethod
+ @ModelView.button_action('stock_split.wizard_split_move')
+ def split_wizard(cls, moves):
+ pass
+
+ def split(self, quantity, uom, count=None):
+ """
+ Split the move into moves of quantity.
+ If count is not defined, the move will be split until the remainder is
+ less than quantity.
+ Return the split moves
+ """
+ pool = Pool()
+ Uom = pool.get('product.uom')
+
+ moves = [self]
+ remainder = Uom.compute_qty(self.uom, self.quantity, uom)
+ if remainder <= quantity:
+ return moves
+ state = self.state
+ self.write([self], {
+ 'state': 'draft',
+ })
+ self.write([self], {
+ 'quantity': quantity,
+ 'uom': uom.id,
+ })
+ remainder -= quantity
+ if count:
+ count -= 1
+ while (remainder > quantity
+ and (count or count is None)):
+ with Transaction().set_context(_stock_move_split=True):
+ moves.extend(self.copy([self], {
+ 'quantity': quantity,
+ 'uom': uom.id,
+ }))
+ remainder -= quantity
+ if count:
+ count -= 1
+ remainder = uom.round(remainder)
+ assert remainder >= 0
+ if remainder:
+ with Transaction().set_context(_stock_move_split=True):
+ moves.extend(self.copy([self], {
+ 'quantity': remainder,
+ 'uom': uom.id,
+ }))
+ self.write(moves, {
+ 'state': state,
+ })
+ return moves
+
+
+class SplitMoveStart(ModelView):
+ 'Split Move'
+ __name__ = 'stock.move.split.start'
+ count = fields.Integer('Counts', help='The limit number of moves.')
+ quantity = fields.Float("Quantity", digits='uom', required=True)
+ uom = fields.Many2One('product.uom', 'Uom', required=True,
+ domain=[
+ ('category', '=', Eval('uom_category')),
+ ])
+ uom_category = fields.Many2One('product.uom.category', 'Uom Category',
+ readonly=True)
+
+
+class SplitMove(Wizard):
+ 'Split Move'
+ __name__ = 'stock.move.split'
+ start = StateView('stock.move.split.start',
+ 'stock_split.split_start_view_form', [
+ Button('Cancel', 'end', 'tryton-cancel'),
+ Button('Split', 'split', 'tryton-ok', default=True),
+ ])
+ split = StateTransition()
+
+ def default_start(self, fields):
+ return {
+ 'uom': self.record.uom.id,
+ 'uom_category': self.record.uom.category.id,
+ }
+
+ def transition_split(self):
+ self.record.split(
+ self.start.quantity, self.start.uom, self.start.count)
+ return 'end'
+
+
+class _ShipmentSplit(ModelView):
+
+ @classmethod
+ def __setup__(cls):
+ super(_ShipmentSplit, cls).__setup__()
+ cls._buttons.update({
+ 'split_wizard': {
+ 'readonly': Eval('state') != 'draft',
+ 'invisible': Eval('state') != 'draft',
+ 'depends': ['state'],
+ },
+ })
+
+ @classmethod
+ @ModelView.button_action('stock_split.wizard_split_shipment')
+ def split_wizard(cls, shipments):
+ pass
+
+
+class ShipmentInReturn(_ShipmentSplit, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.in.return'
+
+
+class ShipmentOut(_ShipmentSplit, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.out'
+
+
+class ShipmentInternal(_ShipmentSplit, metaclass=PoolMeta):
+ __name__ = 'stock.shipment.internal'
+
+
+class SplitShipment(Wizard):
+ "Split Shipment"
+ __name__ = 'stock.shipment.split'
+ start = StateView('stock.shipment.split.start',
+ 'stock_split.shipment_split_start_view_form', [
+ Button("Cancel", 'end', 'tryton-cancel'),
+ Button("Split", 'split', 'tryton-ok', default=True),
+ ])
+ split = StateTransition()
+
+ def get_moves(self, shipment):
+ if shipment.__name__ == 'stock.shipment.out':
+ return shipment.outgoing_moves
+ elif shipment.__name__ in {
+ 'stock.shipment.in.return',
+ 'stock.shipment.internal',
+ }:
+ return shipment.moves
+
+ def default_start(self, fields):
+ moves = self.get_moves(self.record)
+ move_ids = [m.id for m in moves if m.state == 'draft']
+ return {
+ 'domain_moves': move_ids,
+ }
+
+ def transition_split(self):
+ pool = Pool()
+ Move = pool.get('stock.move')
+ shipment = self.record
+ Shipment = self.model
+ if shipment.state != 'draft':
+ raise ValueError("Wrong shipment state")
+ if not set(self.start.moves).issubset(self.start.domain_moves):
+ raise ValueError("Invalid moves, %s != %s" % (self.start.moves,
+ self.start.domain_moves))
+
+ if Shipment.__name__ == 'stock.shipment.out':
+ Move.draft(shipment.inventory_moves)
+ Move.delete(
+ [m for m in shipment.inventory_moves if m.state == 'draft'])
+
+ shipment, = Shipment.copy([shipment], default={'moves': None})
+ Move.write(list(self.start.moves), {'shipment': str(shipment)})
+ return 'end'
+
+
+class SplitShipmentStart(ModelView):
+ "Split Shipment"
+ __name__ = 'stock.shipment.split.start'
+ moves = fields.Many2Many(
+ 'stock.move', None, None, "Moves",
+ domain=[('id', 'in', Eval('domain_moves'))],
+ help="The selected moves will be sent in the new shipment.")
+ domain_moves = fields.Many2Many('stock.move', None, None, "Domain Moves")
diff --git a/modules/stock_split/stock.xml b/modules/stock_split/stock.xml
new file mode 100644
index 0000000000..94f1b452e3
--- /dev/null
+++ b/modules/stock_split/stock.xml
@@ -0,0 +1,99 @@
+
+
+
+
+
+ tryton-stock-split
+ icons/tryton-stock-split.svg
+
+
+
+ Split Move
+ stock.move.split
+ stock.move
+
+
+
+ stock.move
+
+ move_form
+
+
+
+ stock.move
+
+ move_tree
+
+
+
+ stock.move
+
+ move_tree
+
+
+
+ stock.move
+
+ move_tree
+
+
+
+ stock.move.split.start
+ form
+ split_start_form
+
+
+ split_wizard
+ Split
+
+
+
+
+ stock.shipment.in.return
+
+ shipment_split_form
+
+
+
+ split_wizard
+ Split
+
+
+
+
+ stock.shipment.out
+
+ shipment_split_form
+
+
+
+ split_wizard
+ Split
+
+
+
+
+ stock.shipment.internal
+
+ shipment_split_form
+
+
+
+ split_wizard
+ Split
+
+
+
+
+ Split Shipment
+ stock.shipment.split
+
+
+
+ stock.shipment.split.start
+ form
+ shipment_split_start_form
+
+
+
diff --git a/modules/stock_split/tests/__init__.py b/modules/stock_split/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_split/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_split/tests/scenario_stock_split_shipment.rst b/modules/stock_split/tests/scenario_stock_split_shipment.rst
new file mode 100644
index 0000000000..4707242a65
--- /dev/null
+++ b/modules/stock_split/tests/scenario_stock_split_shipment.rst
@@ -0,0 +1,96 @@
+====================
+Stock Split Shipment
+====================
+
+Imports::
+
+ >>> from decimal import Decimal
+
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+
+Activate modules::
+
+ >>> config = activate_modules('stock_split')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create customer::
+
+ >>> Party = Model.get('party.party')
+ >>> customer = Party(name="Customer")
+ >>> customer.save()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> Product = Model.get('product.product')
+ >>> unit, = ProductUom.find([('name', '=', "Unit")])
+ >>> template = ProductTemplate()
+ >>> template.name = "Product"
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template.save()
+ >>> product, = template.products
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+
+Create shipment with 2 lines::
+
+ >>> Shipment = Model.get('stock.shipment.out')
+ >>> Move = Model.get('stock.move')
+
+ >>> shipment1 = Shipment()
+ >>> shipment1.customer = customer
+
+ >>> for i in range(1, 3):
+ ... move = shipment1.outgoing_moves.new()
+ ... move.product = product
+ ... move.uom = unit
+ ... move.quantity = i
+ ... move.from_location = output_loc
+ ... move.to_location = customer_loc
+ ... move.unit_price = Decimal(1)
+ ... move.currency = company.currency
+
+ >>> shipment1.save()
+ >>> move1, move2 = shipment1.outgoing_moves
+
+Set to waiting and go back to draft to get inventory moves::
+
+ >>> shipment1.click('wait')
+ >>> shipment1.click('draft')
+ >>> len(shipment1.inventory_moves)
+ 2
+
+Split shipment::
+
+ >>> split_shipment = Wizard('stock.shipment.split', [shipment1])
+ >>> len(split_shipment.form.domain_moves)
+ 2
+ >>> split_shipment.form.moves.append(Move(move2.id))
+ >>> split_shipment.execute('split')
+
+ >>> shipment2, = Shipment.find([('id', '!=', shipment1.id)])
+
+ >>> move, = shipment1.outgoing_moves
+ >>> move.id == move1.id
+ True
+ >>> len(shipment1.inventory_moves)
+ 0
+
+ >>> move, = shipment2.outgoing_moves
+ >>> move.id == move2.id
+ True
diff --git a/modules/stock_split/tests/test_module.py b/modules/stock_split/tests/test_module.py
new file mode 100644
index 0000000000..c2c46a99eb
--- /dev/null
+++ b/modules/stock_split/tests/test_module.py
@@ -0,0 +1,90 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.modules.company.tests import (
+ CompanyTestMixin, create_company, set_company)
+from trytond.pool import Pool
+from trytond.tests.test_tryton import ModuleTestCase, with_transaction
+
+
+class StockSplitTestCase(CompanyTestMixin, ModuleTestCase):
+ 'Test Stock Lot module'
+ module = 'stock_split'
+
+ @with_transaction()
+ def test_split(self):
+ 'Test split'
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ Template = pool.get('product.template')
+ Product = pool.get('product.product')
+ Location = pool.get('stock.location')
+ Move = pool.get('stock.move')
+
+ unit, = Uom.search([('name', '=', 'Unit')])
+ template, = Template.create([{
+ 'name': 'Test Split',
+ 'type': 'goods',
+ 'default_uom': unit.id,
+ }])
+ product, = Product.create([{
+ 'template': template.id,
+ }])
+ input_, = Location.search([('code', '=', 'IN')])
+ storage, = Location.search([('code', '=', 'STO')])
+ company = create_company()
+ with set_company(company):
+
+ def create_move(quantity):
+ move, = Move.create([{
+ 'product': product.id,
+ 'uom': unit.id,
+ 'quantity': quantity,
+ 'from_location': input_.id,
+ 'to_location': storage.id,
+ 'company': company.id,
+ }])
+ return move
+
+ move = create_move(10)
+ moves = move.split(5, unit)
+ self.assertEqual(len(moves), 2)
+ self.assertEqual([m.quantity for m in moves], [5, 5])
+
+ move = create_move(13)
+ moves = move.split(5, unit)
+ self.assertEqual(len(moves), 3)
+ self.assertEqual([m.quantity for m in moves], [5, 5, 3])
+
+ move = create_move(7)
+ moves = move.split(8, unit)
+ self.assertEqual(moves, [move])
+ self.assertEqual(move.quantity, 7)
+
+ move = create_move(20)
+ moves = move.split(5, unit, count=2)
+ self.assertEqual(len(moves), 3)
+ self.assertEqual([m.quantity for m in moves], [5, 5, 10])
+
+ move = create_move(20)
+ moves = move.split(5, unit, count=4)
+ self.assertEqual(len(moves), 4)
+ self.assertEqual([m.quantity for m in moves], [5, 5, 5, 5])
+
+ move = create_move(10)
+ moves = move.split(5, unit, count=3)
+ self.assertEqual(len(moves), 2)
+ self.assertEqual([m.quantity for m in moves], [5, 5])
+
+ move = create_move(10)
+ Move.write([move], {
+ 'state': 'assigned',
+ })
+ moves = move.split(5, unit)
+ self.assertEqual(len(moves), 2)
+ self.assertEqual([m.quantity for m in moves], [5, 5])
+ self.assertEqual([m.state for m in moves],
+ ['assigned', 'assigned'])
+
+
+del ModuleTestCase
diff --git a/modules/stock_split/tests/test_scenario.py b/modules/stock_split/tests/test_scenario.py
new file mode 100644
index 0000000000..dc1d23e7e5
--- /dev/null
+++ b/modules/stock_split/tests/test_scenario.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import load_doc_tests
+
+
+def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_split/tox.ini b/modules/stock_split/tox.ini
new file mode 100644
index 0000000000..27fc6d27de
--- /dev/null
+++ b/modules/stock_split/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_split/* -m unittest discover -s tests
+ coverage report --include=./**/stock_split/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_split/tryton.cfg b/modules/stock_split/tryton.cfg
new file mode 100644
index 0000000000..ec73702285
--- /dev/null
+++ b/modules/stock_split/tryton.cfg
@@ -0,0 +1,7 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ stock
+xml:
+ stock.xml
diff --git a/modules/stock_split/view/move_form.xml b/modules/stock_split/view/move_form.xml
new file mode 100644
index 0000000000..5b7e3e3dc4
--- /dev/null
+++ b/modules/stock_split/view/move_form.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/stock_split/view/move_tree.xml b/modules/stock_split/view/move_tree.xml
new file mode 100644
index 0000000000..e7d5b40807
--- /dev/null
+++ b/modules/stock_split/view/move_tree.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/stock_split/view/shipment_split_form.xml b/modules/stock_split/view/shipment_split_form.xml
new file mode 100644
index 0000000000..be65c958f3
--- /dev/null
+++ b/modules/stock_split/view/shipment_split_form.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/stock_split/view/shipment_split_start_form.xml b/modules/stock_split/view/shipment_split_start_form.xml
new file mode 100644
index 0000000000..9f3d153e97
--- /dev/null
+++ b/modules/stock_split/view/shipment_split_start_form.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/modules/stock_split/view/split_start_form.xml b/modules/stock_split/view/split_start_form.xml
new file mode 100644
index 0000000000..df7c25c065
--- /dev/null
+++ b/modules/stock_split/view/split_start_form.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/modules/stock_supply/.drone.yml b/modules/stock_supply/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_supply/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_supply/.flake8 b/modules/stock_supply/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_supply/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_supply/.isort.cfg b/modules/stock_supply/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_supply/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_supply/CHANGELOG b/modules/stock_supply/CHANGELOG
new file mode 100644
index 0000000000..1d6bac73f6
--- /dev/null
+++ b/modules/stock_supply/CHANGELOG
@@ -0,0 +1,122 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add warehouses selection to supply stock wizard
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+* Add cron job to supply stock
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+* Make order point's minimal quantity required
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+* Ceil purchase request quantity
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+* Add warning for late customer moves
+* Change supply period into TimeDelta
+* Add support for overflowing quantities
+* Merge supply into one wizard
+* Improve computation of max lead time
+* Generate request internal shipments recursively
+* Do not create purchase request if other order point exists
+
+Version 4.2.0 - 2016-11-28
+* Bug fixes (see mercurial logs for details)
+* Add configuration for the supply period
+
+Version 4.0.0 - 2016-05-02
+* Bug fixes (see mercurial logs for details)
+* Move purchase request to purchase_request module
+* Add Python3 support
+* Add searcher on purchase
+* Adding exception state on the purchase requests
+
+Version 3.8.0 - 2015-11-02
+* Bug fixes (see mercurial logs for details)
+* Generate purchase requests even if rounding set the quantity to 0
+* Add searcher on purchase_request's state
+* Add default internal provisioning per location
+
+Version 3.6.0 - 2015-04-20
+* Bug fixes (see mercurial logs for details)
+* Add support for PyPy
+* Add relate from product to order points
+
+Version 3.4.0 - 2014-10-20
+* Bug fixes (see mercurial logs for details)
+* Allow to calculate purchase requests filtered by warehouse
+
+Version 3.2.0 - 2014-04-21
+* Bug fixes (see mercurial logs for details)
+
+Version 3.0.0 - 2013-10-21
+* Bug fixes (see mercurial logs for details)
+* Add wizard to create internal shipments
+* Add warning for late supplier moves when creating purchase request
+
+Version 2.8.0 - 2013-04-22
+* Bug fixes (see mercurial logs for details)
+* find_best_supplier doesn't optimize anymore on the delivery delay
+
+Version 2.6.0 - 2012-10-22
+* Bug fixes (see mercurial logs for details)
+* Generate also purchase requests for assets
+
+Version 2.4.0 - 2012-04-24
+* Bug fixes (see mercurial logs for details)
+* Warehouse is not always required
+* get_shortage works on a list of products
+* Group purchases using a key
+
+Version 2.2.0 - 2011-10-25
+* Bug fixes (see mercurial logs for details)
+* Add wizard to create purchase requests
+
+Version 2.0.0 - 2011-04-27
+* Bug fixes (see mercurial logs for details)
+
+Version 1.8.0 - 2010-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 1.6.0 - 2010-05-13
+* Bug fixes (see mercurial logs for details)
+
+Version 1.4.0 - 2009-10-19
+* Bug fixes (see mercurial logs for details)
+
+Version 1.2.0 - 2009-04-20
+* Bug fixes (see mercurial logs for details)
+* Allow egg installation
+
+Version 1.0.0 - 2008-11-17
+* Initial release
diff --git a/modules/stock_supply/COPYRIGHT b/modules/stock_supply/COPYRIGHT
new file mode 100644
index 0000000000..3e56d98c19
--- /dev/null
+++ b/modules/stock_supply/COPYRIGHT
@@ -0,0 +1,17 @@
+Copyright (C) 2013-2019 NaN-tic.
+Copyright (C) 2008-2022 Cédric Krier.
+Copyright (C) 2008-2013 Bertrand Chenal.
+Copyright (C) 2008-2022 B2CK SPRL.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_supply/LICENSE b/modules/stock_supply/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_supply/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_supply/MANIFEST.in b/modules/stock_supply/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_supply/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_supply/README.rst b/modules/stock_supply/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_supply/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_supply/__init__.py b/modules/stock_supply/__init__.py
new file mode 100644
index 0000000000..fe0c557161
--- /dev/null
+++ b/modules/stock_supply/__init__.py
@@ -0,0 +1,26 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import (
+ ir, location, order_point, product, purchase_request, shipment, stock)
+
+
+def register():
+ Pool.register(
+ order_point.OrderPoint,
+ product.Product,
+ product.ProductSupplier,
+ purchase_request.PurchaseConfiguration,
+ purchase_request.PurchaseConfigurationSupplyPeriod,
+ purchase_request.PurchaseRequest,
+ shipment.ShipmentInternal,
+ location.Location,
+ location.LocationLeadTime,
+ stock.SupplyStart,
+ ir.Cron,
+ module='stock_supply', type_='model')
+ Pool.register(
+ stock.Supply,
+ module='stock_supply', type_='wizard')
diff --git a/modules/stock_supply/doc/index.rst b/modules/stock_supply/doc/index.rst
new file mode 100644
index 0000000000..4242b81b73
--- /dev/null
+++ b/modules/stock_supply/doc/index.rst
@@ -0,0 +1,47 @@
+Stock Supply Module
+###################
+
+The Stock Supply module add automatic supply mechanisms and introduce
+the concepts of order point.
+
+Order Point
+***********
+
+An order point define minimum, maximum and target quantities for a product on a
+location.
+
+* The minimum quantity is the threshold quantity below which the provisioning
+ process will be triggered.
+
+* The maximum quantity is the threshold quantity above which the overflowing
+ process will be triggered.
+
+* The target quantity is the quantity that will be found in the location after
+ the provisioning / overflowing process has been completed.
+
+An order point also define a type which can be:
+
+* Internal
+
+ An Internal order point is defined on a Storage location, it also defines a
+ provisioning and/or an overflowing location. If the minimum quantity is
+ reached it will result in the creation of an internal shipment between the
+ provisioning location and the Storage location. If the maximum quantity is
+ reached it will result in the creation of an internal shipment between the
+ storage location and the overflowing location.
+
+* Purchase
+
+ A Purchase order point is defined on a warehouse location. If the
+ minimal quantity is reached on the warehouse it will result in a
+ purchase request.
+
+The internal shipments and purchase requests are created by the supply wizard
+with respect to stock levels and existing shipments and requests. The
+stock levels are computed between the next two supply dates computed over the
+Supply Period from the configuration (default: 1 day). If the stock level of a
+product without order point on the given warehouse is below zero, a purchase
+request is also created. The same happens if the stock level of a storage
+location with a provisioning location is below zero. Likewise, if the stock
+level of a storage is above zero and an overflow location is defined on the
+location then an internal shipment will be created.
diff --git a/modules/stock_supply/exceptions.py b/modules/stock_supply/exceptions.py
new file mode 100644
index 0000000000..887d396e96
--- /dev/null
+++ b/modules/stock_supply/exceptions.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.exceptions import UserWarning
+from trytond.model.exceptions import ValidationError
+
+
+class SupplyWarning(UserWarning):
+ pass
+
+
+class OrderPointValidationError(ValidationError):
+ pass
diff --git a/modules/stock_supply/ir.py b/modules/stock_supply/ir.py
new file mode 100644
index 0000000000..27960e0359
--- /dev/null
+++ b/modules/stock_supply/ir.py
@@ -0,0 +1,14 @@
+# The COPYRIGHT file at the top level of this repository contains the full
+# copyright notices and license terms.
+from trytond.pool import PoolMeta
+
+
+class Cron(metaclass=PoolMeta):
+ __name__ = 'ir.cron'
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls.method.selection.extend([
+ ('stock.order_point|supply_stock', "Supply Stock"),
+ ])
diff --git a/modules/stock_supply/locale/bg.po b/modules/stock_supply/locale/bg.po
new file mode 100644
index 0000000000..04a49347a5
--- /dev/null
+++ b/modules/stock_supply/locale/bg.po
@@ -0,0 +1,214 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Пренареждания"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Местонахождение на провизии"
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Фирма"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "Местоположение"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr "Максимално количество"
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr "Минимално количество"
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "Продукт"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Местонахождение на провизии"
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr "Местонахождение на съхранение"
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "Вид"
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr "Единица"
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr "Местонахождение на склад"
+
+#, fuzzy
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr "Местонахождение на склад"
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Пренареждания"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Пренареждания"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "All"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Вътрешно"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Управление на покупки"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+"Разрешено е само едно пренареждане за всяка двойка продукт-местонахождение."
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr ""
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Пренареждане"
+
+#, fuzzy
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Вътрешно"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Покупка"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr "Вид пренареждане"
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr "Информация за продукт"
+
+#, fuzzy
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "Създаване"
+
+#, fuzzy
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "Отказ"
diff --git a/modules/stock_supply/locale/ca.po b/modules/stock_supply/locale/ca.po
new file mode 100644
index 0000000000..0c8d46b435
--- /dev/null
+++ b/modules/stock_supply/locale/ca.po
@@ -0,0 +1,206 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Regles de proveïment"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Període de subministre"
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Període de subministre"
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "Ubicació de excessos"
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Ubicació de l'aprovisionament"
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "Ubicació"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr "Quantitat màxima"
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr "Quantitat mínima"
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "Ubicació de excessos"
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "Producte"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Ubicació de l'aprovisionament"
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr "Ubicació d'emmagatzematge"
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr "Quantitat desitjada"
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "Tipus"
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr "Unitat"
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr "Magatzem"
+
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr "Magatzems"
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr "Deixeu-lo buit per no tenir una ubicació d'excessos per defecte."
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr "Deixeu-lo buit per no tenir una ubicació de proveïment per defecte."
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr "Si es deixa en blanc s'utilitzen tots els magatzems."
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Regles de proveïment"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Regles de proveïment"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Regles de proveïment"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Aprovisiona existències"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "Tot"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Intern"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Compra"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr "Existeixen moviments de client endarrerits."
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr "Existeixen moviments de proveïdor endarrerits."
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"No es pot definir dos regles d'aprovisionament amb ubicacions oposades(\n"
+"de la \"ubicació d'emmagatzemament\" a la \"ubicació d'aprovisionament\" i viceversa)."
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"No es pot definir dos regles d'aprovisionament amb ubicacions oposades\n"
+"(de la \"ubicació d'emmagatzemament\" a la \"ubicació d'aprovisionament\" i viceversa)."
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+"Només es permet una regla de proveïment per cada combinació de producte-"
+"ubicació."
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr "Usuari a les empreses"
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Regles de proveïment"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Aprovisiona existències"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr "Configuració del període d'aprovisionament en compres"
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Regla de proveïment"
+
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Aprovisionament d'existències"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Aprovisiona existències"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Intern"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Compra"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr "Tipus de regla de proveïment"
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr "Informació del producte"
+
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Aprovisionar existències?"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "Crea"
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "Cancel·la"
diff --git a/modules/stock_supply/locale/cs.po b/modules/stock_supply/locale/cs.po
new file mode 100644
index 0000000000..b22f731e23
--- /dev/null
+++ b/modules/stock_supply/locale/cs.po
@@ -0,0 +1,207 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr ""
+
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "All"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Internal"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Purchase"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Internal"
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Purchase"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr ""
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Supply Stock"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr ""
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_supply/locale/de.po b/modules/stock_supply/locale/de.po
new file mode 100644
index 0000000000..a61a2a3bc8
--- /dev/null
+++ b/modules/stock_supply/locale/de.po
@@ -0,0 +1,208 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Bestellpunkte"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Beschaffungszeitraum"
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Beschaffungszeitraum"
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "Lager für Überschüsse"
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Bereitstellungsort"
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Unternehmen"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "Lagerort"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr "Maximale Menge"
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr "Minimale Menge"
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "Lager für Überschüsse"
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "Artikel"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Bereitstellungsort"
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr "Lagerort"
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr "Zielmenge"
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "Typ"
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr "Einheit"
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr "Logistikstandort"
+
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr "Logistikstandorte"
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+"Leer lassen, wenn kein Lagerort für Überschüsse verwendet werden soll."
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+"Leer lassen, wenn kein Standardbereitstellungsort verwendet werden soll."
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr "Leer lassen, um alle Logistikstandorte zu verwenden."
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Bestellpunkte"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Bestellpunkte"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Bestellpunkte"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Waren- und Materialbedarf ermitteln"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "Alle"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Intern"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Einkauf"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr "Einige Warenbewegungen zu Kunden sind verspätet."
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr "Einige Warenbewegungen von Lieferanten sind verspätet."
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"Zwei Bestellpunkte eines gleichen Artikels mit sich widersprechenden Lagerorten können nicht erstellt werden\n"
+"(von \"Lagerort für Überschüsse\" zu \"Bereitstellungsort\" und umgekehrt)."
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"Zwei Bestellpunkte eines gleichen Artikels mit entgegengesetzten Lagerorten können nicht erstellt werden\n"
+"(von \"Lagerzone\" zu \"Bereitstellungsort\" und umgekehrt)."
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+"Es ist nur ein Bestellpunkt für jede Paarung aus Artikel und Lagerort "
+"erlaubt."
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr "Benutzer im Unternehmen"
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Bestellpunkte"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Waren- und Materialbedarf ermitteln"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr "Einstellungen Einkauf Beschaffungszeitraum"
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Bestellpunkt"
+
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Waren- und Materialbedarf ermitteln"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Waren- und Materialbedarf ermitteln"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Intern"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Einkauf"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr "Typ Bestellpunkt"
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr "Info"
+
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Waren- und Materialbedarf ermitteln?"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "Erstellen"
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "Abbrechen"
diff --git a/modules/stock_supply/locale/es.po b/modules/stock_supply/locale/es.po
new file mode 100644
index 0000000000..82aa24519a
--- /dev/null
+++ b/modules/stock_supply/locale/es.po
@@ -0,0 +1,207 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Reglas de abastecimiento"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Periodo de suministro"
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Periodo de suministro"
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "Ubicación de excesos"
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Ubicación del abastecimiento"
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "Ubicación"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr "Cantidad máxima"
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr "Cantidad mínima"
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "Ubicación de excesos"
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "Producto"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Ubicación del abastecimiento"
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr "Ubicación interna"
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr "Cantidad destino"
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "Tipo"
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr "Unidad"
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr "Ubicación del almacén"
+
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr "Almacenes"
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr "Dejarlo vacío para no tener una ubicación de excesos por defecto."
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+"Dejarlo vacío para no tener una ubicación de abastecimiento por defecto."
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr "Si está vacío se utilizan todos los almacenes."
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Reglas de abastecimiento"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Reglas de abastecimiento"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Reglas de abastecimiento"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Aprovisionar existencias"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "Todo"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Interna"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Compra"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr "Existen movimientos de cliente retrasados."
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr "Existen movimientos de proveedor retrasados."
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"No se puede definir dos reglas de aprovisionamiento con ubicaciones opuestas\n"
+"(de la \"ubicación de almacenamiento\" a la \"ubicación del abastecimiento\" y viceversa)."
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"No se puede definir dos reglas de aprovisionamiento con ubicaciones opuestas\n"
+"(de la \"ubicación de almacenamiento\" a la \"ubicación del abastecimiento\" y viceversa)."
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+"Sólo se permite una regla de abastecimiento por cada combinación de "
+"producto-ubicación."
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr "Usuario en las empresas"
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Reglas de abastecimiento"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Aprovisionar existencias"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr "Configuración del periodo de aprovisionamiento en compras"
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Regla de abastecimiento"
+
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Aprovisionamiento de existencias"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Aprovisionar existencias"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Interno"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Compra"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr "Tipo de regla de abastecimiento"
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr "Información del producto"
+
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Aprovisionar existencias?"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "Crear"
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "Cancelar"
diff --git a/modules/stock_supply/locale/es_419.po b/modules/stock_supply/locale/es_419.po
new file mode 100644
index 0000000000..7825460c4c
--- /dev/null
+++ b/modules/stock_supply/locale/es_419.po
@@ -0,0 +1,202 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr "Ubicación del almacenamiento"
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr "Ubicación de la bodega"
+
+#, fuzzy
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr "Ubicación de la bodega"
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr ""
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Interna"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr ""
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr ""
+
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Interna"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr ""
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr ""
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr ""
+
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr ""
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr ""
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_supply/locale/et.po b/modules/stock_supply/locale/et.po
new file mode 100644
index 0000000000..5ad87d9c7c
--- /dev/null
+++ b/modules/stock_supply/locale/et.po
@@ -0,0 +1,203 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Tellimiskohad"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Tarneaeg"
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Tarneaeg"
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Ettevõte"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "Asukoht"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr "Maksimaalne kogus"
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr "Minimaalne kogus"
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "Toode"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr "Lao asukoht"
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "Tüüp"
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr "Ühik"
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr "Lao asukoht"
+
+#, fuzzy
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr "Lao asukoht"
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Tellimiskohad"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Tellimiskohad"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Tellimiskohad"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "hanke ladu"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "Kõik"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Sisemine"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Ost"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr "Kasutaja ettevõttes"
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Tellimiskohad"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Hanke ladu"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr "Hanke seadistus - hanke periood"
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Tellimiskohad"
+
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Hanke ladu"
+
+#, fuzzy
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "hanke ladu"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Sisemine"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Ost"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr "Tellimiskoha tüüp"
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr "Toote info"
+
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Hanke ladu?"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "Loo"
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "Tühista"
diff --git a/modules/stock_supply/locale/fa.po b/modules/stock_supply/locale/fa.po
new file mode 100644
index 0000000000..0c35a6a3e5
--- /dev/null
+++ b/modules/stock_supply/locale/fa.po
@@ -0,0 +1,208 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "نقاط سفارش"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "دوره عرضه"
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "دوره عرضه"
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "مکان لبریز شده"
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "مکان تأمیین کننده"
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "شرکت"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "مکان"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr "مقدار حداکثر"
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr "حداقل مقدار"
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "مکان لبریز شده"
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "محصول"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "مکان تأمیین کننده"
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr "محل انبار"
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr "مقدار هدف"
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "نوع"
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr "واحد"
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr "مکان انبار"
+
+#, fuzzy
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr "مکان انبار"
+
+#, fuzzy
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr "برای بدون لبریز پیش فرض، خالی بگذارید"
+
+#, fuzzy
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr "برای تأمین کننده غیرپیش فرض خالی بگذارید"
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "نقاط سفارش"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "نقاط سفارش"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "نقاط سفارش"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "عرضه موجودی"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "همه"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "داخلی"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "خرید"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr "برخی از جابجایی مشتری تأخیر دارند."
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr "برخی از جابجایی تأمین کننده تأخیر دارند."
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"شما نمیتوانید برای هر محصول دو نقطه سفارش با مکان های متفاوت تعریف کنید\n"
+"(از محل سرریز به محل تأمین و برعکس)."
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"شما نمیتوانید برای هر محصول دو نقطه سفارش با مکان های متفاوت تعریف کنید\n"
+"(از محل ذخیره کالا به محل تأمین و برعکس)."
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr "برای هر جفت مکان - محصول فقط یک نقطه سفارش مجاز است."
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "نقاط سفارش"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "عرضه موجودی"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr "پیکربندی خرید ؛ دوره تامین"
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "نقطه سفارش"
+
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "عرضه موجودی"
+
+#, fuzzy
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "عرضه موجودی"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "داخلی"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "خرید"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr "نوع نقطه سفارش"
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr "اطلاعات محصول"
+
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "عرضه موجودی؟"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "ایجاد"
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "انصراف"
diff --git a/modules/stock_supply/locale/fi.po b/modules/stock_supply/locale/fi.po
new file mode 100644
index 0000000000..b22f731e23
--- /dev/null
+++ b/modules/stock_supply/locale/fi.po
@@ -0,0 +1,207 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr ""
+
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "All"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Internal"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Purchase"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Internal"
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Purchase"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr ""
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Supply Stock"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr ""
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_supply/locale/fr.po b/modules/stock_supply/locale/fr.po
new file mode 100644
index 0000000000..5bef57938e
--- /dev/null
+++ b/modules/stock_supply/locale/fr.po
@@ -0,0 +1,206 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Règles d'approvisionnement"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Période d'approvisionnement"
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Période d'approvisionnement"
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "Emplacement de surplus"
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Emplacement d’approvisionnement"
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Société"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "Emplacement"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr "Quantité maximale"
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr "Quantité minimale"
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "Emplacement de surplus"
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "Produit"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Emplacement d'approvisionnement"
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr "Emplacement de stockage"
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr "Quantité souhaitée"
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "Type"
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr "Unité"
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr "Entrepôt"
+
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr "Entrepôts"
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr "Laissez vide pour aucun surplus par défaut."
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr "Laissez vide pour aucun approvisionnement par défaut."
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr "Si vide, tous les entrepôts sont utilisés."
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Règles d'approvisionnement"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Règles d'approvisionnement"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Règles d'approvisionnement"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Approvisionner le stock"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "Toutes"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Internes"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Achats"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr "Il y a des mouvements clients qui sont en retard."
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr "Il y a des mouvements fournisseurs qui sont en retard."
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"Vous ne pouvez pas définir deux règles d'approvisionnement pour le même produit avec des emplacements opposés\n"
+"(d' « Emplacement de stockage » à « Emplacement d'approvisionnement » et vice versa)."
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"Vous ne pouvez pas définir deux règles d'approvisionnement pour le même produit avec des emplacements opposés\n"
+"(d' « Emplacement de stockage » à « Emplacement d'approvisionnement » et vice versa)."
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+"Une seule règle d'approvisionnement est autorisée par paire produit-"
+"emplacement."
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr "Utilisateur dans les sociétés"
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Règles d'approvisionnement"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Approvisionner le stock"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr "Configuration d'achat Période d'approvisionnement"
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Règle d'approvisionnement"
+
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Approvisionner le stock"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Approvisionner le stock"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Interne"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Achat"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr "Type de Règle d'approvisionnement"
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr "Info produit"
+
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Approvisionner le stock ?"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "Créer"
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "Annuler"
diff --git a/modules/stock_supply/locale/hu.po b/modules/stock_supply/locale/hu.po
new file mode 100644
index 0000000000..83289d8189
--- /dev/null
+++ b/modules/stock_supply/locale/hu.po
@@ -0,0 +1,207 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Újrarendelési pontok"
+
+#, fuzzy
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Beszerzési időszak"
+
+#, fuzzy
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Beszerzési időszak"
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "Felesleg tárhelye"
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Beszerzési tárhely"
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Cég"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "Tárhely"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr "Maximális készletszint"
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr "Minimális készletszint"
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "Felesleg tárhelye"
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "Termék"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Beszerzési tárhely"
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr "Cél tárhely"
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr "Cél készletszint"
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "Áruellátás forrása"
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr "Mértékegység"
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr "Raktár"
+
+#, fuzzy
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr "Raktár"
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+"Hagyja üresen, ha nem szeretné a tárhelyen lévő készletet automatikusan "
+"átvezetni a felesleg tárhelyre."
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+"Hagyja üresen, ha nem szeretne a tárhelyre érkező rendelésekhez "
+"automatikusan készletet a beszerzési tárhelyről áthozni."
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Újrarendelési pontok"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Újrarendelési pontok"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Újrarendelési pontok"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Áruellátás futtatása"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "összes"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "belső"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "beszállítótól"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr "Némelyik vevőkhöz induló készletmozgás már késésben van."
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr "Némelyik beszállítótól érkező készletmozgás már késésben van."
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr "Egy termék/tárhely kombinációnak csak egy újrarendelési pontja lehet."
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Újrarendelési pontok"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Áruellátás futtatása"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr ""
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Újrarendelési pont"
+
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Áruellátás futtatása"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Áruellátás futtatása"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "belső"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "beszállítótól"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr "Áruellátási beállítások"
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr "Termék és mennyiség"
+
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Létrehozza a beszerzési igényeket/belső szállítmányokat?"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "Létrehozás"
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "Mégse"
diff --git a/modules/stock_supply/locale/id.po b/modules/stock_supply/locale/id.po
new file mode 100644
index 0000000000..e233823933
--- /dev/null
+++ b/modules/stock_supply/locale/id.po
@@ -0,0 +1,201 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Perusahaan"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "Lokasi"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "Produk"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr "Lokasi Penyimpanan"
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr ""
+
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Pembelian"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr "Pengguna di dalam perusahaan"
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr ""
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr ""
+
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr ""
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Pembelian"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr ""
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr ""
+
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr ""
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "Buat"
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "Batal"
diff --git a/modules/stock_supply/locale/it.po b/modules/stock_supply/locale/it.po
new file mode 100644
index 0000000000..1bea85832d
--- /dev/null
+++ b/modules/stock_supply/locale/it.po
@@ -0,0 +1,213 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Periodo di fornitura"
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Periodo di fornitura"
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Azienda"
+
+#, fuzzy
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "Luogo"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "Prodotto"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "Tipo"
+
+#, fuzzy
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr "Unità"
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr ""
+
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr "Magazzini"
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "Tutti"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Internal"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Acquisto"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Internal"
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Acquisto"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr ""
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Fornire Stock?"
+
+#, fuzzy
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "Creazione"
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "Annulla"
diff --git a/modules/stock_supply/locale/lo.po b/modules/stock_supply/locale/lo.po
new file mode 100644
index 0000000000..49dd82800d
--- /dev/null
+++ b/modules/stock_supply/locale/lo.po
@@ -0,0 +1,216 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "ຫ້ອງການ/ສຳນັກງານ"
+
+#, fuzzy
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "ບ່ອນຢູ່"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "ຜະລິດຕະພັນ"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "ຮູບແບບ"
+
+#, fuzzy
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr "ໜ່ວຍ"
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr ""
+
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "ທັງໝົດ"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Internal"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "ສັ່ງຊື້"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Internal"
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "ສັ່ງຊື້"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr ""
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "ສ້າງ"
+
+#, fuzzy
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "ຍົກເລີກ"
diff --git a/modules/stock_supply/locale/lt.po b/modules/stock_supply/locale/lt.po
new file mode 100644
index 0000000000..94b923a458
--- /dev/null
+++ b/modules/stock_supply/locale/lt.po
@@ -0,0 +1,207 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Organizacija"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr ""
+
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "All"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Internal"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Purchase"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Internal"
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Purchase"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr ""
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Supply Stock"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr ""
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_supply/locale/nl.po b/modules/stock_supply/locale/nl.po
new file mode 100644
index 0000000000..868971dc4b
--- /dev/null
+++ b/modules/stock_supply/locale/nl.po
@@ -0,0 +1,204 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Bestel regels"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Leveringstermijn"
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Leveringstermijn"
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "locatie overschot (surplus)"
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "provisioning Locatie"
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Bedrijf"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "Plaats"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr "Maximale hoeveelheid"
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr "Minimale hoeveelheid"
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "Overschot locatie"
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "Product"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "provisioning Locatie"
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr "Opslaglocatie"
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr "Gewenste hoeveelheid"
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "Type"
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr "Eenheid"
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr "Magazijnlocatie"
+
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr "Magazijnen"
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr "Laat leeg als er geen opslaglocatie wordt gebruikt voor overschotten."
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr "Laat leeg als er geen opslaglocatie wordt gebruikt voor overschotten."
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr "Indien leeg worden alle magazijnen gebruikt."
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Bestel punten"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Bestel punten"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Bestel punten"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "voorraad levering"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "Alle"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Intern"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Aankoop"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr "Er zijn enkele klantbewegingen die te laat zijn."
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr "Er zijn enkele leveranciersbewegingen die te laat zijn."
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"U kunt voor hetzelfde product niet twee bestelpunten met tegenovergestelde locaties definiëren\n"
+"(van \"Overstock locatie\" naar \"provisielocatie\" en vice versa)."
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"U kunt voor hetzelfde product niet twee bestelpunten met tegenovergestelde locaties definiëren\n"
+"(van \"Opslag locatie\" naar \"provisielocatie\" en vice versa)."
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr "Per product-locatiepaar is slechts één bestelpunt toegestaan."
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr "Gebruiker in het bedrijf"
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Bestel punten"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "voorraad levering"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr "configuratie aankoop verwervingsperiode"
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Bestelpunt"
+
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "voorraad levering"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "voorraad levering"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Intern"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Aankoop"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr "Bestelpunttype"
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr "Product informatie"
+
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Voorraad inslaan?"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "Maken"
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "Annuleer"
diff --git a/modules/stock_supply/locale/pl.po b/modules/stock_supply/locale/pl.po
new file mode 100644
index 0000000000..8576a0d1f7
--- /dev/null
+++ b/modules/stock_supply/locale/pl.po
@@ -0,0 +1,213 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Firma"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "Lokalizacja"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr "Maksymalna ilość"
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr "Minimalna ilość"
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "Produkt"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr "Docelowa ilość"
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "Typ"
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr "Jednostka"
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr "Lokalizacja magazynu"
+
+#, fuzzy
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr "Lokalizacja magazynu"
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "All"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Internal"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Purchase"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Internal"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Zakup"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr ""
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr "Informacja o produkcie"
+
+#, fuzzy
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Supply Stock"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "Utwórz"
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "Anuluj"
diff --git a/modules/stock_supply/locale/pt.po b/modules/stock_supply/locale/pt.po
new file mode 100644
index 0000000000..4f0d4bd1c3
--- /dev/null
+++ b/modules/stock_supply/locale/pt.po
@@ -0,0 +1,224 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Regras de Abastecimento"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Período de Abastecimento"
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Período de Abastecimento"
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "Localização de Transbordo"
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Localização do Abastecimento"
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "Localização"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr "Quantidade máxima"
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr "Quantidade mínima"
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "Localização de Transbordo"
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "Produto"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Localização do Abastecimento"
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr "Local de armazenamento"
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr "Quantidade Alvo"
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "Tipo"
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr "Unidade"
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr "Localização do Almoxarifado"
+
+#, fuzzy
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr "Localização do Almoxarifado"
+
+#, fuzzy
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr "Deixe vazio para nenhum transbordo padrão"
+
+#, fuzzy
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr "Deixe vazio para nenhum abastecimento padrão"
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "All"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Internal"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Purchase"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+#, fuzzy
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"Você não pode definir duas regras de abastecimento no mesmo produto com "
+"localizações opostas (de \"Local de Armazenamento\" para \"Local de "
+"Transbordo\" e vice versa)."
+
+#, fuzzy
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"Você não pode definir duas regras de abastecimento no mesmo produto com "
+"localizações opostas (de \"Local de Armazenamento\" para \"Local de "
+"Transbordo\" e vice versa)."
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+"Apenas uma regras de abastecimento é permitida para cada par produto-"
+"localização."
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr "Configurações de Compra Período de Abastecimento"
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Regra de Abastecimento"
+
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Abastecer Estoque"
+
+#, fuzzy
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Interno"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Compra"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr "Tipo de Regra de Abastecimento"
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr "Informação do Produto"
+
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Abastecer Estoque?"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "Criar"
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "Cancelar"
diff --git a/modules/stock_supply/locale/ro.po b/modules/stock_supply/locale/ro.po
new file mode 100644
index 0000000000..672da636dc
--- /dev/null
+++ b/modules/stock_supply/locale/ro.po
@@ -0,0 +1,200 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Companie"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "Produs"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr ""
+
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr ""
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr ""
+
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr ""
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr ""
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr ""
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr ""
+
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr ""
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr ""
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_supply/locale/ru.po b/modules/stock_supply/locale/ru.po
new file mode 100644
index 0000000000..0ab90993dd
--- /dev/null
+++ b/modules/stock_supply/locale/ru.po
@@ -0,0 +1,215 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Точки заказа"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Местоположение резервирования"
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Организация"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "Местоположение"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr "Максимальное кол-во"
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr "Минимальное кол-во"
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "Продукт"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Местоположение резервирования"
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr "Хранение Местоположение"
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "Тип"
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr "Единица измерения"
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr "Местополжение на складе"
+
+#, fuzzy
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr "Местополжение на складе"
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Точки заказа"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Точки заказа"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "Все"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Внутренний"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Покупки"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+"Возможна только одна точка заказа для каждой пары продукт-местоположение."
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr ""
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Точка заказа"
+
+#, fuzzy
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Внутренний"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Покупки"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr "Типы точек заказа"
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr "Информация о продукте"
+
+#, fuzzy
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "Создать"
+
+#, fuzzy
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "Отменить"
diff --git a/modules/stock_supply/locale/sl.po b/modules/stock_supply/locale/sl.po
new file mode 100644
index 0000000000..9dc8261740
--- /dev/null
+++ b/modules/stock_supply/locale/sl.po
@@ -0,0 +1,220 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Točke naročanja"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Obdobje dobave"
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Obdobje dobave"
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "Prelivna lokacija"
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Preskrbovalna lokacija"
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr "Družba"
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr "Lokacija"
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr "Največja količina"
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr "Najmanjša količina"
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr "Prelivna lokacija"
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr "Izdelek"
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr "Preskrbovalna lokacija"
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr "Shramba"
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr "Ciljna količina"
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "Tip"
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr "enota"
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr "Skladišče"
+
+#, fuzzy
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr "Skladišče"
+
+#, fuzzy
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr "Pusti prazno, če ni privzetega preliva"
+
+#, fuzzy
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr "Pusti prazno, če ni privzete preskrbe"
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "All"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Internal"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Purchase"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+#, fuzzy
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"Dveh točk naročanja z nasprotnima lokacijama (iz \"Shrambe\" na "
+"\"Preskrbovalno lokacijo\" in obratno) ni možno določiti na istem izdelku."
+
+#, fuzzy
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+"Dveh točk naročanja z nasprotnima lokacijama (iz \"Shrambe\" na "
+"\"Preskrbovalno lokacijo\" in obratno) ni možno določiti na istem izdelku."
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr "Dovoljena je samo ena točka naročanja za vsak par izdelek - lokacija."
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr "Konfiguracija obdobja nabavne dobave"
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Točka naročanja"
+
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Oskrba zaloge"
+
+#, fuzzy
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Interno"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Nabavni nalog"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr "Tip točke naročanja"
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr "Podatek o izdelku"
+
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Oskrba zaloge?"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr "Izdelava"
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "Prekliči"
diff --git a/modules/stock_supply/locale/tr.po b/modules/stock_supply/locale/tr.po
new file mode 100644
index 0000000000..b22f731e23
--- /dev/null
+++ b/modules/stock_supply/locale/tr.po
@@ -0,0 +1,207 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr ""
+
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "All"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Internal"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Purchase"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Internal"
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Purchase"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr ""
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Supply Stock"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr ""
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_supply/locale/uk.po b/modules/stock_supply/locale/uk.po
new file mode 100644
index 0000000000..d4425612b4
--- /dev/null
+++ b/modules/stock_supply/locale/uk.po
@@ -0,0 +1,200 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr ""
+
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr ""
+
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr ""
+
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr ""
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr ""
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr ""
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr ""
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr ""
+
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr ""
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr ""
+
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr ""
diff --git a/modules/stock_supply/locale/zh_CN.po b/modules/stock_supply/locale/zh_CN.po
new file mode 100644
index 0000000000..ae902dfa54
--- /dev/null
+++ b/modules/stock_supply/locale/zh_CN.po
@@ -0,0 +1,210 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:product.product,order_points:"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "field:purchase.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:purchase.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:stock.location,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.location,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:stock.order_point,location:"
+msgid "Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,max_quantity:"
+msgid "Maximal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,min_quantity:"
+msgid "Minimal Quantity"
+msgstr ""
+
+msgctxt "field:stock.order_point,overflowing_location:"
+msgid "Overflowing Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:stock.order_point,provisioning_location:"
+msgid "Provisioning Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,storage_location:"
+msgid "Storage Location"
+msgstr ""
+
+msgctxt "field:stock.order_point,target_quantity:"
+msgid "Target Quantity"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:stock.order_point,type:"
+msgid "Type"
+msgstr "类型"
+
+msgctxt "field:stock.order_point,unit:"
+msgid "Unit"
+msgstr ""
+
+msgctxt "field:stock.order_point,warehouse_location:"
+msgid "Warehouse Location"
+msgstr ""
+
+msgctxt "field:stock.supply.start,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "help:stock.location,overflowing_location:"
+msgid "Leave empty for no default overflowing."
+msgstr ""
+
+msgctxt "help:stock.location,provisioning_location:"
+msgid "Leave empty for no default provisioning."
+msgstr ""
+
+msgctxt "help:stock.supply.start,warehouses:"
+msgid "If empty all warehouses are used."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_order_point_form_relate2"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.action,name:act_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_all"
+msgid "All"
+msgstr "全部"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_internal"
+msgid "Internal"
+msgstr "Internal"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_purchase"
+msgid "Purchase"
+msgstr "Purchase"
+
+msgctxt "model:ir.message,text:msg_late_customer_moves"
+msgid "There are some customer moves that are late."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_supplier_moves"
+msgid "There are some supplier moves that are late."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_overflowing_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Overflowing Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt ""
+"model:ir.message,text:msg_order_point_concurrent_provisioning_location_internal"
+msgid ""
+"You cannot define for the same product two order points with opposite locations\n"
+"(from \"Storage Location\" to \"Provisioning Location\" and vice versa)."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_order_point_unique"
+msgid "Only one order point is allowed for each product-location pair."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_order_point_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_order_point_form"
+msgid "Order Points"
+msgstr "Order Points"
+
+msgctxt "model:ir.ui.menu,name:menu_stock_supply"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+msgctxt "model:purchase.configuration.supply_period,name:"
+msgid "Purchase Configuration Supply Period"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:stock.order_point,name:"
+msgid "Order Point"
+msgstr "Order Points"
+
+#, fuzzy
+msgctxt "model:stock.supply.start,name:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:ir.cron,method:"
+msgid "Supply Stock"
+msgstr "Supply Stock"
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Internal"
+msgstr "Internal"
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Purchase"
+msgstr "Purchase"
+
+msgctxt "view:stock.order_point:"
+msgid "Order Point Type"
+msgstr ""
+
+msgctxt "view:stock.order_point:"
+msgid "Product Info"
+msgstr ""
+
+#, fuzzy
+msgctxt "view:stock.supply.start:"
+msgid "Supply Stock?"
+msgstr "Supply Stock"
+
+msgctxt "wizard_button:stock.supply,start,create_:"
+msgid "Create"
+msgstr ""
+
+#, fuzzy
+msgctxt "wizard_button:stock.supply,start,end:"
+msgid "Cancel"
+msgstr "取消"
diff --git a/modules/stock_supply/location.py b/modules/stock_supply/location.py
new file mode 100644
index 0000000000..1f16351707
--- /dev/null
+++ b/modules/stock_supply/location.py
@@ -0,0 +1,64 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import datetime
+
+from trytond.model import fields
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Eval
+
+
+class Location(metaclass=PoolMeta):
+ __name__ = 'stock.location'
+
+ provisioning_location = fields.Many2One('stock.location',
+ 'Provisioning Location',
+ states={
+ 'invisible': Eval('type') != 'storage',
+ },
+ domain=[
+ ('type', 'in', ['storage', 'view']),
+ ],
+ help='Leave empty for no default provisioning.')
+ overflowing_location = fields.Many2One('stock.location',
+ 'Overflowing Location',
+ states={
+ 'invisible': Eval('type') != 'storage',
+ },
+ domain=[
+ ('type', 'in', ['storage', 'view']),
+ ],
+ help='Leave empty for no default overflowing.')
+
+
+class LocationLeadTime(metaclass=PoolMeta):
+ __name__ = 'stock.location.lead_time'
+
+ @classmethod
+ def get_max_lead_time(cls):
+ """Return the biggest lead time
+ increased by the maximum extra lead times"""
+ lead_time = datetime.timedelta(0)
+ lead_times = cls.search([])
+ if lead_times:
+ lead_time = sum(
+ (r.lead_time for r in lead_times if r.lead_time),
+ datetime.timedelta(0))
+ extra_lead_times = cls._get_extra_lead_times()
+ if extra_lead_times:
+ lead_time += max(extra_lead_times)
+ return lead_time
+
+ @classmethod
+ def _get_extra_lead_times(cls):
+ 'Return a list of extra lead time'
+ pool = Pool()
+ ProductSupplier = pool.get('purchase.product_supplier')
+ extra = []
+
+ product_suppliers = ProductSupplier.search(
+ [('lead_time', '!=', None)],
+ order=[('lead_time', 'DESC')], limit=1)
+ if product_suppliers:
+ product_supplier, = product_suppliers
+ extra.append(product_supplier.lead_time)
+ return extra
diff --git a/modules/stock_supply/location.xml b/modules/stock_supply/location.xml
new file mode 100644
index 0000000000..82f4599b8c
--- /dev/null
+++ b/modules/stock_supply/location.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ stock.location
+
+ location_form
+
+
+
diff --git a/modules/stock_supply/message.xml b/modules/stock_supply/message.xml
new file mode 100644
index 0000000000..dc06b0313f
--- /dev/null
+++ b/modules/stock_supply/message.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+ Only one order point is allowed for each product-location pair.
+
+
+ You cannot define for the same product two order points with opposite locations
+(from "Storage Location" to "Provisioning Location" and vice versa).
+
+
+ You cannot define for the same product two order points with opposite locations
+(from "Overflowing Location" to "Provisioning Location" and vice versa).
+
+
+ There are some supplier moves that are late.
+
+
+ There are some customer moves that are late.
+
+
+
diff --git a/modules/stock_supply/order_point.py b/modules/stock_supply/order_point.py
new file mode 100644
index 0000000000..747612d8df
--- /dev/null
+++ b/modules/stock_supply/order_point.py
@@ -0,0 +1,249 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from sql import Null
+
+from trytond.i18n import gettext
+from trytond.model import ModelSQL, ModelView, fields
+from trytond.pool import Pool
+from trytond.pyson import Equal, Eval, If, In, Not
+from trytond.transaction import Transaction
+
+from .exceptions import OrderPointValidationError
+
+
+class OrderPoint(ModelSQL, ModelView):
+ """
+ Order Point
+ Provide a way to define a supply policy for each
+ product on each locations. Order points on warehouse are
+ considered by the supply scheduler to generate purchase requests.
+ """
+ __name__ = 'stock.order_point'
+ product = fields.Many2One(
+ 'product.product', "Product", required=True,
+ domain=[
+ ('type', '=', 'goods'),
+ ('consumable', '=', False),
+ ('purchasable', 'in', If(Equal(Eval('type'), 'purchase'),
+ [True], [True, False])),
+ ],
+ context={
+ 'company': Eval('company', -1),
+ },
+ depends={'company'})
+ warehouse_location = fields.Many2One(
+ 'stock.location', 'Warehouse Location',
+ domain=[('type', '=', 'warehouse')],
+ states={
+ 'invisible': Not(Equal(Eval('type'), 'purchase')),
+ 'required': Equal(Eval('type'), 'purchase'),
+ })
+ storage_location = fields.Many2One(
+ 'stock.location', "Storage Location",
+ domain=[('type', '=', 'storage')],
+ states={
+ 'invisible': Not(Equal(Eval('type'), 'internal')),
+ 'required': Equal(Eval('type'), 'internal'),
+ })
+ location = fields.Function(fields.Many2One('stock.location', 'Location'),
+ 'get_location', searcher='search_location')
+ provisioning_location = fields.Many2One(
+ 'stock.location', 'Provisioning Location',
+ domain=[('type', 'in', ['storage', 'view'])],
+ states={
+ 'invisible': Not(Equal(Eval('type'), 'internal')),
+ 'required': ((Eval('type') == 'internal')
+ & (Eval('min_quantity', None) != None)), # noqa: E711
+ })
+ overflowing_location = fields.Many2One(
+ 'stock.location', 'Overflowing Location',
+ domain=[('type', 'in', ['storage', 'view'])],
+ states={
+ 'invisible': Eval('type') != 'internal',
+ 'required': ((Eval('type') == 'internal')
+ & (Eval('max_quantity', None) != None)), # noqa: E711
+ })
+ type = fields.Selection(
+ [('internal', 'Internal'),
+ ('purchase', 'Purchase')],
+ "Type", required=True)
+ min_quantity = fields.Float(
+ "Minimal Quantity", digits='unit',
+ states={
+ # required for purchase and production types
+ 'required': Eval('type') != 'internal',
+ },
+ domain=['OR',
+ ('min_quantity', '=', None),
+ ('min_quantity', '<=', Eval('target_quantity', 0)),
+ ])
+ target_quantity = fields.Float(
+ "Target Quantity", digits='unit', required=True,
+ domain=[
+ ['OR',
+ ('min_quantity', '=', None),
+ ('target_quantity', '>=', Eval('min_quantity', 0)),
+ ],
+ ['OR',
+ ('max_quantity', '=', None),
+ ('target_quantity', '<=', Eval('max_quantity', 0)),
+ ],
+ ])
+ max_quantity = fields.Float(
+ "Maximal Quantity", digits='unit',
+ states={
+ 'invisible': Eval('type') != 'internal',
+ },
+ domain=['OR',
+ ('max_quantity', '=', None),
+ ('max_quantity', '>=', Eval('target_quantity', 0)),
+ ])
+ company = fields.Many2One('company.company', 'Company', required=True,
+ domain=[
+ ('id', If(In('company', Eval('context', {})), '=', '!='),
+ Eval('context', {}).get('company', -1)),
+ ])
+ unit = fields.Function(fields.Many2One('product.uom', 'Unit'), 'get_unit')
+
+ @classmethod
+ def __register__(cls, module_name):
+ cursor = Transaction().connection.cursor()
+ sql_table = cls.__table__()
+ table = cls.__table_handler__(module_name)
+
+ # Migration from 4.2
+ table.drop_constraint('check_max_qty_greater_min_qty')
+ table.not_null_action('min_quantity', 'remove')
+ table.not_null_action('max_quantity', 'remove')
+ target_qty_exist = table.column_exist('target_quantity')
+
+ super(OrderPoint, cls).__register__(module_name)
+
+ # Migration from 4.2
+ if not target_qty_exist:
+ cursor.execute(*sql_table.update(
+ [sql_table.target_quantity, sql_table.max_quantity],
+ [sql_table.max_quantity, Null]))
+
+ @staticmethod
+ def default_type():
+ return "purchase"
+
+ @fields.depends('product', '_parent_product.default_uom')
+ def on_change_product(self):
+ self.unit = None
+ if self.product:
+ self.unit = self.product.default_uom
+
+ def get_unit(self, name):
+ return self.product.default_uom.id
+
+ @classmethod
+ def validate(cls, orderpoints):
+ super(OrderPoint, cls).validate(orderpoints)
+ cls.check_concurrent_internal(orderpoints)
+ cls.check_uniqueness(orderpoints)
+
+ @classmethod
+ def check_concurrent_internal(cls, orders):
+ """
+ Ensure that there is no 'concurrent' internal order
+ points. I.E. no two order point with opposite location for the
+ same product and same company.
+ """
+ internals = cls.search([
+ ('id', 'in', [o.id for o in orders]),
+ ('type', '=', 'internal'),
+ ])
+ if not internals:
+ return
+
+ for location_name in [
+ 'provisioning_location', 'overflowing_location']:
+ query = []
+ for op in internals:
+ if getattr(op, location_name, None) is None:
+ continue
+ arg = ['AND',
+ ('product', '=', op.product.id),
+ (location_name, '=', op.storage_location.id),
+ ('storage_location', '=',
+ getattr(op, location_name).id),
+ ('company', '=', op.company.id),
+ ('type', '=', 'internal')]
+ query.append(arg)
+ if query and cls.search(['OR'] + query):
+ raise OrderPointValidationError(
+ gettext('stock_supply'
+ '.msg_order_point_concurrent_%s_internal' %
+ location_name))
+
+ @staticmethod
+ def _type2field(type=None):
+ t2f = {
+ 'purchase': 'warehouse_location',
+ 'internal': 'storage_location',
+ }
+ if type is None:
+ return t2f
+ else:
+ return t2f[type]
+
+ @classmethod
+ def check_uniqueness(cls, orders):
+ """
+ Ensure uniqueness of order points. I.E that there is no several
+ order point for the same location, the same product and the
+ same company.
+ """
+ query = ['OR']
+ for op in orders:
+ field = cls._type2field(op.type)
+ arg = ['AND',
+ ('product', '=', op.product.id),
+ (field, '=', getattr(op, field).id),
+ ('id', '!=', op.id),
+ ('company', '=', op.company.id),
+ ]
+ query.append(arg)
+ if cls.search(query):
+ raise OrderPointValidationError(
+ gettext('stock_supply.msg_order_point_unique'))
+
+ def get_rec_name(self, name):
+ return "%s @ %s" % (self.product.name, self.location.name)
+
+ @classmethod
+ def search_rec_name(cls, name, clause):
+ return ['OR',
+ ('location.rec_name',) + tuple(clause[1:]),
+ ('product.rec_name',) + tuple(clause[1:]),
+ ]
+
+ def get_location(self, name):
+ if self.type == 'purchase':
+ return self.warehouse_location.id
+ elif self.type == 'internal':
+ return self.storage_location.id
+
+ @classmethod
+ def search_location(cls, name, domain=None):
+ clauses = ['OR']
+ for type, field in cls._type2field().items():
+ clauses.append([
+ ('type', '=', type),
+ (field,) + tuple(domain[1:]),
+ ])
+ return clauses
+
+ @staticmethod
+ def default_company():
+ return Transaction().context.get('company')
+
+ @classmethod
+ def supply_stock(cls):
+ pool = Pool()
+ StockSupply = pool.get('stock.supply', type='wizard')
+ session_id, _, _ = StockSupply.create()
+ StockSupply.execute(session_id, {}, 'create_')
+ StockSupply.delete(session_id)
diff --git a/modules/stock_supply/order_point.xml b/modules/stock_supply/order_point.xml
new file mode 100644
index 0000000000..56ba26bdd0
--- /dev/null
+++ b/modules/stock_supply/order_point.xml
@@ -0,0 +1,85 @@
+
+
+
+
+
+ stock.order_point
+ form
+ order_point_form
+
+
+ stock.order_point
+ tree
+ order_point_tree
+
+
+
+ Order Points
+ stock.order_point
+
+
+
+
+
+
+
+
+
+
+
+
+ Purchase
+
+
+
+
+
+ Internal
+
+
+
+
+
+ All
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ User in companies
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_supply/product.py b/modules/stock_supply/product.py
new file mode 100644
index 0000000000..e4b2feb19e
--- /dev/null
+++ b/modules/stock_supply/product.py
@@ -0,0 +1,25 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import datetime
+
+from trytond.model import fields
+from trytond.pool import Pool, PoolMeta
+
+
+class Product(metaclass=PoolMeta):
+ __name__ = "product.product"
+ order_points = fields.One2Many(
+ 'stock.order_point', 'product', 'Order Points')
+
+
+class ProductSupplier(metaclass=PoolMeta):
+ __name__ = 'purchase.product_supplier'
+
+ def get_supply_period(self):
+ 'Return the supply period for the purchase request'
+ pool = Pool()
+ Configuration = pool.get('purchase.configuration')
+ config = Configuration(1)
+ supply_period = config.get_multivalue(
+ 'supply_period', company=self.company.id)
+ return supply_period or datetime.timedelta(1)
diff --git a/modules/stock_supply/product.xml b/modules/stock_supply/product.xml
new file mode 100644
index 0000000000..db24724809
--- /dev/null
+++ b/modules/stock_supply/product.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+ Order Points
+ stock.order_point
+
+
+
+ form_relate
+ product.product,-1
+
+
+
+
+ Order Points
+ stock.order_point
+
+
+
+ form_relate
+ product.template,-1
+
+
+
+
diff --git a/modules/stock_supply/purchase_request.py b/modules/stock_supply/purchase_request.py
new file mode 100644
index 0000000000..b1f65c3d2e
--- /dev/null
+++ b/modules/stock_supply/purchase_request.py
@@ -0,0 +1,361 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import datetime
+import operator
+from collections import defaultdict
+
+from trytond.model import ModelSQL, ValueMixin, fields
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import TimeDelta
+from trytond.tools import grouped_slice
+from trytond.transaction import Transaction
+
+supply_period = fields.TimeDelta(
+ "Supply Period",
+ domain=['OR',
+ ('supply_period', '=', None),
+ ('supply_period', '>=', TimeDelta()),
+ ])
+
+
+class PurchaseConfiguration(metaclass=PoolMeta):
+ __name__ = 'purchase.configuration'
+ supply_period = fields.MultiValue(supply_period)
+
+
+class PurchaseConfigurationSupplyPeriod(ModelSQL, ValueMixin):
+ "Purchase Configuration Supply Period"
+ __name__ = 'purchase.configuration.supply_period'
+ supply_period = supply_period
+
+
+class PurchaseRequest(metaclass=PoolMeta):
+ 'Purchase Request'
+ __name__ = 'purchase.request'
+
+ @classmethod
+ def _get_origin(cls):
+ origins = super(PurchaseRequest, cls)._get_origin()
+ return origins | {'stock.order_point'}
+
+ @classmethod
+ def generate_requests(cls, products=None, warehouses=None):
+ """
+ For each product compute the purchase request that must be
+ created today to meet product outputs.
+
+ If products is specified it will compute the purchase requests
+ for the selected products.
+
+ If warehouses is specified it will compute the purchase request
+ necessary for the selected warehouses.
+ """
+ pool = Pool()
+ OrderPoint = pool.get('stock.order_point')
+ Product = pool.get('product.product')
+ Location = pool.get('stock.location')
+ User = pool.get('res.user')
+ company = User(Transaction().user).company
+
+ if warehouses is None:
+ # fetch warehouses:
+ warehouses = Location.search([
+ ('type', '=', 'warehouse'),
+ ])
+ warehouse_ids = [w.id for w in warehouses]
+ # fetch order points
+ order_points = OrderPoint.search([
+ ('warehouse_location', '!=', None),
+ ('company', '=', company.id if company else None),
+ ])
+ # index them by product
+ product2ops = {}
+ product2ops_other = {}
+ for order_point in order_points:
+ if order_point.type == 'purchase':
+ dict_ = product2ops
+ else:
+ dict_ = product2ops_other
+ dict_[
+ (order_point.warehouse_location.id, order_point.product.id)
+ ] = order_point
+
+ if products is None:
+ # fetch goods and assets
+ # ordered by ids to speedup reduce_ids in products_by_location
+ products = Product.search([
+ ('type', 'in', ['goods', 'assets']),
+ ('consumable', '=', False),
+ ('purchasable', '=', True),
+ ], order=[('id', 'ASC')])
+ product_ids = [p.id for p in products]
+ # aggregate product by minimum supply date
+ date2products = defaultdict(list)
+ for product in products:
+ min_date, max_date = cls.get_supply_dates(
+ product, company=company.id)
+ date2products[min_date, max_date].append(product)
+
+ # compute requests
+ new_requests = []
+ for (min_date, max_date), dates_products in date2products.items():
+ for sub_products in grouped_slice(dates_products):
+ sub_products = list(sub_products)
+ product_ids = [p.id for p in sub_products]
+ with Transaction().set_context(
+ forecast=True,
+ stock_date_end=min_date):
+ pbl = Product.products_by_location(warehouse_ids,
+ with_childs=True, grouping_filter=(product_ids,))
+ for warehouse_id in warehouse_ids:
+ min_date_qties = defaultdict(int,
+ ((x, pbl.pop((warehouse_id, x), 0))
+ for x in product_ids))
+ # Do not compute shortage for product
+ # with different order point
+ product_ids = [
+ p.id for p in sub_products
+ if (warehouse_id, p.id) not in product2ops_other]
+ # Search for shortage between min-max
+ shortages = cls.get_shortage(
+ warehouse_id, product_ids, min_date, max_date,
+ min_date_qties=min_date_qties,
+ order_points=product2ops)
+
+ for product in sub_products:
+ if product.id not in shortages:
+ continue
+ shortage_date, product_quantity = shortages[product.id]
+ if shortage_date is None or product_quantity is None:
+ continue
+ order_point = product2ops.get(
+ (warehouse_id, product.id))
+ # generate request values
+ request = cls.compute_request(product,
+ warehouse_id, shortage_date, product_quantity,
+ company, order_point)
+ new_requests.append(request)
+
+ # delete purchase requests without a purchase line
+ products = set(products)
+ reqs = cls.search([
+ ('state', '=', 'draft'),
+ ('origin', 'like', 'stock.order_point,%'),
+ ])
+ reqs = [r for r in reqs
+ if r.product in products and r.warehouse in warehouses]
+ cls.delete(reqs)
+ new_requests = cls.compare_requests(new_requests)
+
+ cls.create_requests(new_requests)
+
+ @classmethod
+ def create_requests(cls, new_requests):
+ to_save = []
+ for new_req in new_requests:
+ if new_req.supply_date == datetime.date.max:
+ new_req.supply_date = None
+ if new_req.computed_quantity > 0:
+ to_save.append(new_req)
+ cls.save(to_save)
+
+ @classmethod
+ def compare_requests(cls, new_requests):
+ """
+ Compare new_requests with already existing request to avoid
+ to re-create existing requests.
+ """
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ Request = pool.get('purchase.request')
+
+ requests = Request.search([
+ ('purchase_line.moves', '=', None),
+ ('purchase_line.purchase.state', '!=', 'cancelled'),
+ ('origin', 'like', 'stock.order_point,%'),
+ ])
+ # Fetch data from existing requests
+ existing_req = {}
+ for request in requests:
+ pline = request.purchase_line
+ # Skip incoherent request
+ if (request.product != pline.product
+ or request.warehouse != pline.purchase.warehouse):
+ continue
+ # Take smallest amount between request and purchase line
+ pline_qty = Uom.compute_qty(pline.unit, pline.quantity,
+ pline.product.default_uom, round=False)
+ quantity = min(request.computed_quantity, pline_qty)
+
+ existing_req.setdefault(
+ (request.product.id, request.warehouse.id),
+ []).append({
+ 'supply_date': (
+ request.supply_date or datetime.date.max),
+ 'quantity': quantity,
+ })
+
+ for i in existing_req.values():
+ i.sort(key=lambda r: r['supply_date'])
+
+ # Update new requests to take existing requests into account
+ new_requests.sort(key=operator.attrgetter('supply_date'))
+ for new_req in new_requests:
+ for old_req in existing_req.get(
+ (new_req.product.id, new_req.warehouse.id), []):
+ if old_req['supply_date'] <= new_req.supply_date:
+ new_req.computed_quantity = max(0.0,
+ new_req.computed_quantity - old_req['quantity'])
+ new_req.quantity = Uom.compute_qty(
+ new_req.product.default_uom, new_req.computed_quantity,
+ new_req.uom, round=False)
+ new_req.quantity = new_req.uom.ceil(new_req.quantity)
+ old_req['quantity'] = max(0.0,
+ old_req['quantity'] - new_req.computed_quantity)
+ else:
+ break
+
+ return new_requests
+
+ @classmethod
+ def get_supply_dates(cls, product, **pattern):
+ """
+ Return the interval of earliest supply dates for a product.
+ """
+ Date = Pool().get('ir.date')
+
+ min_date = None
+ max_date = None
+ today = Date.today()
+
+ for product_supplier in product.product_suppliers_used(**pattern):
+ supply_date = product_supplier.compute_supply_date(date=today)
+ if supply_date == datetime.date.max:
+ continue
+ next_day = today + product_supplier.get_supply_period()
+ next_supply_date = product_supplier.compute_supply_date(
+ date=next_day)
+ if (not min_date) or supply_date < min_date:
+ min_date = supply_date
+ if (not max_date) or next_supply_date > max_date:
+ max_date = next_supply_date
+
+ if not min_date:
+ min_date = datetime.date.max
+ max_date = datetime.date.max
+
+ return (min_date, max_date)
+
+ @classmethod
+ def compute_request(cls, product, location_id, shortage_date,
+ product_quantity, company, order_point=None,
+ supplier_pattern=None):
+ """
+ Return the value of the purchase request which will answer to
+ the needed quantity at the given date. I.e: the latest
+ purchase date, the expected supply date and the prefered
+ supplier.
+ """
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ Request = pool.get('purchase.request')
+
+ if supplier_pattern is None:
+ supplier_pattern = {}
+ else:
+ supplier_pattern = supplier_pattern.copy()
+ supplier_pattern['company'] = company.id
+
+ supplier, purchase_date = cls.find_best_supplier(product,
+ shortage_date, **supplier_pattern)
+
+ uom = product.purchase_uom or product.default_uom
+ target_quantity = order_point.target_quantity if order_point else 0.0
+ computed_quantity = target_quantity - product_quantity
+ product_quantity = uom.ceil(product_quantity)
+ quantity = Uom.compute_qty(
+ product.default_uom, computed_quantity, uom, round=False)
+ quantity = uom.ceil(quantity)
+
+ if order_point:
+ origin = 'stock.order_point,%s' % order_point.id
+ else:
+ origin = 'stock.order_point,-1'
+ return Request(product=product,
+ party=supplier and supplier or None,
+ quantity=quantity,
+ uom=uom,
+ computed_quantity=computed_quantity,
+ computed_uom=product.default_uom,
+ purchase_date=purchase_date,
+ supply_date=shortage_date,
+ stock_level=product_quantity,
+ company=company,
+ warehouse=location_id,
+ origin=origin,
+ )
+
+ @classmethod
+ def get_shortage(cls, location_id, product_ids, min_date, max_date,
+ min_date_qties, order_points):
+ """
+ Return for each product the first date between min_date and max_date
+ where the stock quantity is less than the minimal quantity and the
+ smallest stock quantity in the interval or None if there is no date
+ where stock quantity is less than the minimal quantity.
+
+ The minimal quantity comes from the order point or is zero.
+
+ min_date_qty is the quantities for each products at the min_date.
+ order_points is a dictionary that links products to order point.
+ """
+ Product = Pool().get('product.product')
+
+ res_dates = {}
+ res_qties = {}
+
+ min_quantities = defaultdict(float)
+ for product_id in product_ids:
+ order_point = order_points.get((location_id, product_id))
+ if order_point:
+ min_quantities[product_id] = order_point.min_quantity
+
+ with Transaction().set_context(
+ forecast=True,
+ stock_date_start=min_date,
+ stock_date_end=max_date):
+ pbl = Product.products_by_location(
+ [location_id], with_childs=True,
+ grouping=('date', 'product'),
+ grouping_filter=(None, product_ids))
+ pbl_dates = defaultdict(dict)
+ for key, qty in pbl.items():
+ date, product_id = key[1:]
+ pbl_dates[date][product_id] = qty
+
+ current_date = min_date
+ current_qties = min_date_qties.copy()
+ products_to_check = product_ids.copy()
+ while (current_date < max_date) or (current_date == min_date):
+ for product_id in products_to_check:
+ current_qty = current_qties[product_id]
+ min_quantity = min_quantities[product_id]
+ res_qty = res_qties.get(product_id)
+ res_date = res_dates.get(product_id)
+ if min_quantity is not None and current_qty < min_quantity:
+ if not res_date:
+ res_dates[product_id] = current_date
+ if (not res_qty) or (current_qty < res_qty):
+ res_qties[product_id] = current_qty
+
+ if current_date == datetime.date.max:
+ break
+ current_date += datetime.timedelta(1)
+
+ pbl = pbl_dates[current_date]
+ products_to_check.clear()
+ for product_id, qty in pbl.items():
+ current_qties[product_id] += qty
+ products_to_check.append(product_id)
+
+ return {x: (res_dates.get(x), res_qties.get(x)) for x in product_ids}
diff --git a/modules/stock_supply/purchase_request.xml b/modules/stock_supply/purchase_request.xml
new file mode 100644
index 0000000000..ea8a161d8f
--- /dev/null
+++ b/modules/stock_supply/purchase_request.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+ purchase.configuration
+
+ purchase_configuration_form
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_supply/setup.py b/modules/stock_supply/setup.py
new file mode 100755
index 0000000000..d71d5d34c4
--- /dev/null
+++ b/modules/stock_supply/setup.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_supply'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = ['python-sql']
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [get_require_version('proteus')]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module for stock supply',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_supply',
+ },
+ keywords='tryton stock supply',
+ package_dir={'trytond.modules.stock_supply': '.'},
+ packages=(
+ ['trytond.modules.stock_supply']
+ + ['trytond.modules.stock_supply.%s' % p for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_supply': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'Intended Audience :: Manufacturing',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_supply = trytond.modules.stock_supply
+ """,
+ )
diff --git a/modules/stock_supply/shipment.py b/modules/stock_supply/shipment.py
new file mode 100644
index 0000000000..25bc648b7a
--- /dev/null
+++ b/modules/stock_supply/shipment.py
@@ -0,0 +1,182 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import datetime
+from collections import defaultdict
+
+from trytond.model import ModelSQL, ModelView
+from trytond.pool import Pool
+from trytond.tools import grouped_slice
+from trytond.transaction import Transaction
+
+
+class ShipmentInternal(ModelSQL, ModelView):
+ __name__ = 'stock.shipment.internal'
+
+ @classmethod
+ def generate_internal_shipment(cls, clean=True, warehouses=None):
+ """
+ Generate internal shipments to meet order points defined on
+ non-warehouse location.
+
+ If clean is set, it will remove all previous requests.
+ """
+ pool = Pool()
+ OrderPoint = pool.get('stock.order_point')
+ Location = pool.get('stock.location')
+ Product = pool.get('product.product')
+ Date = pool.get('ir.date')
+ User = pool.get('res.user')
+ Move = pool.get('stock.move')
+ LeadTime = pool.get('stock.location.lead_time')
+
+ if warehouses is None:
+ warehouses = Location.search([
+ ('type', '=', 'warehouse'),
+ ])
+
+ user_record = User(Transaction().user)
+ today = Date.today()
+ lead_time = LeadTime.get_max_lead_time()
+
+ if clean:
+ reqs = cls.search([
+ ('state', '=', 'request'),
+ ])
+ cls.delete(reqs)
+
+ # fetch quantities on order points
+ order_points = OrderPoint.search([
+ ('type', '=', 'internal'),
+ ])
+ order_points = [
+ op for op in order_points if op.location.warehouse in warehouses]
+ id2product = {}
+ product2op = {}
+ id2location = {}
+ for op in order_points:
+ id2product[op.product.id] = op.product
+ product2op[
+ (op.storage_location.id, op.product.id)
+ ] = op
+ id2location[op.storage_location.id] = op.storage_location
+ implicit_locations = Location.search(['OR',
+ ('provisioning_location', '!=', None),
+ ('overflowing_location', '!=', None),
+ ])
+ id2location.update({l.id: l for l in implicit_locations})
+ location_ids = list(id2location.keys())
+
+ def get_pbl(start, end, grouping_filter):
+ with Transaction().set_context(
+ forecast=True, stock_date_start=start, stock_date_end=end):
+ return Product.products_by_location(
+ location_ids, with_childs=True,
+ grouping_filter=grouping_filter)
+
+ # ordered by ids to speedup reduce_ids in products_by_location
+ if implicit_locations:
+ products = Product.search([
+ ('type', 'in', ['goods', 'assets']),
+ ], order=[('id', 'ASC')])
+ product_ids = [p.id for p in products]
+ pbl = get_pbl(None, today, None)
+ else:
+ product_ids = list(id2product.keys())
+ product_ids.sort()
+ pbl = defaultdict(int)
+ for sub_product_ids in grouped_slice(product_ids):
+ pbl.update(get_pbl(None, today, (list(sub_product_ids),)))
+
+ shipments = []
+ date = today
+ end_date = date + lead_time
+ current_qties = pbl.copy()
+ while date <= end_date:
+ # Create a list of moves to create
+ moves = {}
+ for location in id2location.values():
+ for product_id in product_ids:
+ qty = current_qties.get((location.id, product_id), 0)
+ op = product2op.get((location.id, product_id))
+ if op:
+ min_qty, max_qty = op.min_quantity, op.max_quantity
+ target_qty = op.target_quantity
+ prov_location = op.provisioning_location
+ over_location = op.overflowing_location
+ elif (location
+ and (location.provisioning_location
+ or location.overflowing_location)):
+ target_qty = 0
+ min_qty = 0 if location.provisioning_location else None
+ max_qty = 0 if location.overflowing_location else None
+ prov_location = location.provisioning_location
+ over_location = location.overflowing_location
+ else:
+ continue
+
+ change_qty = 0
+ if min_qty is not None and qty < min_qty:
+ from_loc = prov_location.id
+ to_loc = location.id
+ change_qty = target_qty - qty
+ elif max_qty is not None and qty > max_qty:
+ from_loc = location.id
+ to_loc = over_location.id
+ change_qty = qty - target_qty
+
+ if change_qty:
+ key = (from_loc, to_loc, product_id)
+ moves[key] = change_qty
+ current_qties[(from_loc, product_id)] -= change_qty
+ current_qties[(to_loc, product_id)] += change_qty
+
+ # Group moves by {from,to}_location
+ to_create = {}
+ for key, qty in moves.items():
+ from_location, to_location, product = key
+ to_create.setdefault(
+ (from_location, to_location), []).append((product, qty))
+ # Create shipments and moves
+ for locations, moves in to_create.items():
+ from_location, to_location = locations
+ shipment = cls(
+ from_location=from_location,
+ to_location=to_location,
+ planned_date=date,
+ state='request',
+ )
+ shipment_moves = []
+ for move in moves:
+ product_id, qty = move
+ product = id2product.setdefault(
+ product_id, Product(product_id))
+ shipment_moves.append(Move(
+ from_location=from_location,
+ to_location=to_location,
+ planned_date=date,
+ product=product,
+ quantity=qty,
+ uom=product.default_uom,
+ company=user_record.company,
+ ))
+ shipment.moves = shipment_moves
+ shipment.planned_start_date = (
+ shipment.on_change_with_planned_start_date())
+ shipments.append(shipment)
+ date += datetime.timedelta(1)
+
+ # Update quantities with next moves
+ if implicit_locations:
+ for key, qty in get_pbl(date, date, None).items():
+ current_qties[key] += qty
+ else:
+ for sub_product_ids in grouped_slice(product_ids):
+ for key, qty in get_pbl(
+ date, date, (list(sub_product_ids),)).items():
+ current_qties[key] += qty
+
+ if shipments:
+ cls.save(shipments)
+ # Split moves through transit to get accurate dates
+ cls._set_transit(shipments)
+ return shipments
diff --git a/modules/stock_supply/stock.py b/modules/stock_supply/stock.py
new file mode 100644
index 0000000000..e5dfd8c8b6
--- /dev/null
+++ b/modules/stock_supply/stock.py
@@ -0,0 +1,140 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.i18n import gettext
+from trytond.model import ModelView, fields
+from trytond.pool import Pool
+from trytond.transaction import Transaction
+from trytond.wizard import (
+ Button, StateAction, StateTransition, StateView, Wizard)
+
+from .exceptions import SupplyWarning
+
+
+class Supply(Wizard):
+ "Supply Stock"
+ __name__ = 'stock.supply'
+ start = StateView(
+ 'stock.supply.start',
+ 'stock_supply.supply_start_view_form', [
+ Button('Cancel', 'end', 'tryton-cancel'),
+ Button('Create', 'create_', 'tryton-ok', default=True),
+ ])
+ create_ = StateTransition()
+ internal = StateAction('stock.act_shipment_internal_form')
+ purchase = StateAction('purchase_request.act_purchase_request_form')
+
+ @classmethod
+ def types(cls):
+ return ['internal', 'purchase']
+
+ @classmethod
+ def next_action(cls, name):
+ types = cls.types()
+ try:
+ return types[types.index(name) + 1]
+ except IndexError:
+ return 'end'
+
+ def transition_create_(self):
+ pool = Pool()
+ Move = pool.get('stock.move')
+ ShipmentInternal = pool.get('stock.shipment.internal')
+ Date = pool.get('ir.date')
+ Warning = pool.get('res.user.warning')
+ today = Date.today()
+ with Transaction().set_context(_check_access=True):
+ if Move.search([
+ ('from_location.type', '=', 'supplier'),
+ ('to_location.type', '=', 'storage'),
+ ('state', '=', 'draft'),
+ ('planned_date', '<', today),
+ ], order=[]):
+ name = '%s.supplier@%s' % (self.__name__, today)
+ if Warning.check(name):
+ raise SupplyWarning(name,
+ gettext('stock_supply.msg_late_supplier_moves'))
+ if Move.search([
+ ('from_location.type', '=', 'storage'),
+ ('to_location.type', '=', 'customer'),
+ ('state', '=', 'draft'),
+ ('planned_date', '<', today),
+ ], order=[]):
+ name = '%s..customer@%s' % (self.__name__, today)
+ if Warning.check(name):
+ raise SupplyWarning(name,
+ gettext('stock_supply.msg_late_customer_moves'))
+
+ first = True
+ created = False
+ while created or first:
+ created = False
+ for type_ in self.types():
+ created |= bool(getattr(self, 'generate_%s' % type_)(first))
+ first = False
+
+ # Remove transit split of request
+ with Transaction().set_context(_check_access=True):
+ shipments = ShipmentInternal.search([
+ ('state', '=', 'request'),
+ ])
+ Move.delete([m for s in shipments for m in s.moves
+ if m.from_location == s.transit_location])
+ for shipment in shipments:
+ Move.write([m for m in shipment.moves], {
+ 'from_location': shipment.from_location.id,
+ 'to_location': shipment.to_location.id,
+ 'planned_date': shipment.planned_date,
+ })
+
+ return self.types()[0]
+
+ def generate_internal(self, clean):
+ pool = Pool()
+ ShipmentInternal = pool.get('stock.shipment.internal')
+ # Use getattr because start is empty when run by cron
+ if getattr(self.start, 'warehouses', None):
+ warehouses = self.start.warehouses
+ else:
+ warehouses = None
+ return ShipmentInternal.generate_internal_shipment(
+ clean=clean, warehouses=warehouses)
+
+ def transition_internal(self):
+ return self.next_action('internal')
+
+ @property
+ def _purchase_parameters(self):
+ parameters = {}
+ # Use getattr because start is empty when run by cron
+ if getattr(self.start, 'warehouses', None):
+ parameters['warehouses'] = self.start.warehouses
+ return parameters
+
+ def generate_purchase(self, clean):
+ pool = Pool()
+ PurchaseRequest = pool.get('purchase.request')
+ PurchaseRequest.generate_requests(**self._purchase_parameters)
+ return False
+
+ def transition_purchase(self):
+ return self.next_action('purchase')
+
+
+class SupplyStart(ModelView):
+ "Supply Stock"
+ __name__ = 'stock.supply.start'
+
+ warehouses = fields.Many2Many(
+ 'stock.location', None, None, "Warehouses",
+ domain=[
+ ('type', '=', 'warehouse'),
+ ],
+ help="If empty all warehouses are used.")
+
+ @classmethod
+ def default_warehouses(cls):
+ pool = Pool()
+ Location = pool.get('stock.location')
+ warehouse = Location.get_default_warehouse()
+ if warehouse:
+ return [warehouse]
diff --git a/modules/stock_supply/stock.xml b/modules/stock_supply/stock.xml
new file mode 100644
index 0000000000..863cbf033d
--- /dev/null
+++ b/modules/stock_supply/stock.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+ Supply Stock
+ stock.supply
+
+
+
+
+
+
+
+
+
+
+
+
+
+ stock.supply.start
+ form
+ supply_start_form
+
+
+
diff --git a/modules/stock_supply/tests/__init__.py b/modules/stock_supply/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_supply/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_supply/tests/scenario_stock_internal_supply.rst b/modules/stock_supply/tests/scenario_stock_internal_supply.rst
new file mode 100644
index 0000000000..acd193eea4
--- /dev/null
+++ b/modules/stock_supply/tests/scenario_stock_internal_supply.rst
@@ -0,0 +1,192 @@
+===========================
+Stock Shipment Out Scenario
+===========================
+
+Imports::
+
+ >>> import datetime
+ >>> from dateutil.relativedelta import relativedelta
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules, set_user
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> today = datetime.date.today()
+
+Activate modules::
+
+ >>> config = activate_modules('stock_supply')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create stock admin user::
+
+ >>> User = Model.get('res.user')
+ >>> Group = Model.get('res.group')
+ >>> stock_admin_user = User()
+ >>> stock_admin_user.name = 'Stock Admin'
+ >>> stock_admin_user.login = 'stock_admin'
+ >>> stock_admin_group, = Group.find([('name', '=', 'Stock Administration')])
+ >>> stock_admin_user.groups.append(stock_admin_group)
+ >>> stock_admin_user.save()
+
+Create stock user::
+
+ >>> stock_user = User()
+ >>> stock_user.name = 'Stock'
+ >>> stock_user.login = 'stock'
+ >>> stock_group, = Group.find([('name', '=', 'Stock')])
+ >>> stock_user.groups.append(stock_group)
+ >>> stock_user.save()
+
+Create product user::
+
+ >>> product_admin_user = User()
+ >>> product_admin_user.name = 'Product'
+ >>> product_admin_user.login = 'product'
+ >>> product_admin_group, = Group.find([
+ ... ('name', '=', 'Product Administration')
+ ... ])
+ >>> product_admin_user.groups.append(product_admin_group)
+ >>> product_admin_user.save()
+
+Create product::
+
+ >>> set_user(product_admin_user)
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template.save()
+ >>> product, = template.products
+
+Get stock locations::
+
+ >>> set_user(stock_admin_user)
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+ >>> lost_loc, = Location.find([('type', '=', 'lost_found')])
+
+Create provisioning location::
+
+ >>> Location = Model.get('stock.location')
+ >>> provisioning_loc = Location()
+ >>> provisioning_loc.name = 'Provisioning Location'
+ >>> provisioning_loc.type = 'storage'
+ >>> provisioning_loc.parent = warehouse_loc
+ >>> provisioning_loc.save()
+
+Create a new storage location::
+
+ >>> sec_storage_loc = Location()
+ >>> sec_storage_loc.name = 'Second Storage'
+ >>> sec_storage_loc.type = 'storage'
+ >>> sec_storage_loc.parent = warehouse_loc
+ >>> sec_storage_loc.provisioning_location = provisioning_loc
+ >>> sec_storage_loc.save()
+
+Create internal order point::
+
+ >>> OrderPoint = Model.get('stock.order_point')
+ >>> order_point = OrderPoint()
+ >>> order_point.product = product
+ >>> order_point.storage_location = storage_loc
+ >>> order_point.provisioning_location = provisioning_loc
+ >>> order_point.type = 'internal'
+ >>> order_point.min_quantity = 10
+ >>> order_point.target_quantity = 15
+ >>> order_point.save()
+
+Create inventory to add enough quantity in Provisioning Location::
+
+ >>> set_user(stock_user)
+ >>> Inventory = Model.get('stock.inventory')
+ >>> inventory = Inventory()
+ >>> inventory.location = provisioning_loc
+ >>> inventory_line = inventory.lines.new(product=product)
+ >>> inventory_line.quantity = 100.0
+ >>> inventory_line.expected_quantity = 0.0
+ >>> inventory.click('confirm')
+ >>> inventory.state
+ 'done'
+
+Execute internal supply::
+
+ >>> ShipmentInternal = Model.get('stock.shipment.internal')
+ >>> set_user(stock_admin_user)
+ >>> Wizard('stock.supply').execute('create_')
+ >>> set_user(stock_user)
+ >>> shipment, = ShipmentInternal.find([])
+ >>> shipment.state
+ 'request'
+ >>> len(shipment.moves)
+ 1
+ >>> move, = shipment.moves
+ >>> move.product.template.name
+ 'Product'
+ >>> move.quantity
+ 15.0
+ >>> move.from_location.name
+ 'Provisioning Location'
+ >>> move.to_location.code
+ 'STO'
+
+Create negative quantity in Second Storage::
+
+ >>> Move = Model.get('stock.move')
+ >>> move = Move()
+ >>> move.product = product
+ >>> move.quantity = 10
+ >>> move.from_location = sec_storage_loc
+ >>> move.to_location = lost_loc
+ >>> move.click('do')
+ >>> move.state
+ 'done'
+
+Execute internal supply::
+
+ >>> set_user(stock_admin_user)
+ >>> Wizard('stock.supply').execute('create_')
+ >>> set_user(stock_user)
+ >>> shipment, = ShipmentInternal.find(
+ ... [('to_location', '=', sec_storage_loc.id)])
+ >>> shipment.state
+ 'request'
+ >>> len(shipment.moves)
+ 1
+ >>> move, = shipment.moves
+ >>> move.product.template.name
+ 'Product'
+ >>> move.quantity
+ 10.0
+ >>> move.from_location.name
+ 'Provisioning Location'
+ >>> move.to_location.name
+ 'Second Storage'
+
+Create stock_supply cron and execute it::
+
+ >>> Cron = Model.get('ir.cron')
+ >>> admin_user, = User.find([('login', '=', 'admin')])
+ >>> set_user(admin_user)
+ >>> shipment.delete()
+ >>> cron = Cron(method='stock.order_point|supply_stock')
+ >>> cron.interval_number = 1
+ >>> cron.interval_type = 'months'
+ >>> cron.click('run_once')
+ >>> shipment, = ShipmentInternal.find(
+ ... [('to_location', '=', sec_storage_loc.id)])
+ >>> shipment.state
+ 'request'
diff --git a/modules/stock_supply/tests/scenario_stock_internal_supply_lead_time.rst b/modules/stock_supply/tests/scenario_stock_internal_supply_lead_time.rst
new file mode 100644
index 0000000000..fbd77c0e5f
--- /dev/null
+++ b/modules/stock_supply/tests/scenario_stock_internal_supply_lead_time.rst
@@ -0,0 +1,144 @@
+========================================
+Stock Internal Supply Lead Time Scenario
+========================================
+
+Imports::
+
+ >>> import datetime
+ >>> from dateutil.relativedelta import relativedelta
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> today = datetime.date.today()
+ >>> tomorrow = today + relativedelta(days=1)
+
+Activate modules::
+
+ >>> config = activate_modules('stock_supply')
+
+Create customer::
+
+ >>> Party = Model.get('party.party')
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template.save()
+ >>> product, = template.products
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> lost_loc, = Location.find([('type', '=', 'lost_found')])
+
+Create second warehouse::
+
+ >>> sec_warehouse_loc, = warehouse_loc.duplicate()
+
+Add lead time between warehouses::
+
+ >>> LeadTime = Model.get('stock.location.lead_time')
+ >>> lead_time = LeadTime()
+ >>> lead_time.warehouse_from = warehouse_loc
+ >>> lead_time.warehouse_to = sec_warehouse_loc
+ >>> lead_time.lead_time = datetime.timedelta(1)
+ >>> lead_time.save()
+
+Create internal order point::
+
+ >>> OrderPoint = Model.get('stock.order_point')
+ >>> order_point = OrderPoint()
+ >>> order_point.product = product
+ >>> order_point.storage_location = sec_warehouse_loc.storage_location
+ >>> order_point.provisioning_location = warehouse_loc.storage_location
+ >>> order_point.type = 'internal'
+ >>> order_point.min_quantity = 10
+ >>> order_point.target_quantity = 15
+ >>> order_point.save()
+
+Create inventory to add enough quantity in first warehouse::
+
+ >>> Inventory = Model.get('stock.inventory')
+ >>> inventory = Inventory()
+ >>> inventory.location = warehouse_loc.storage_location
+ >>> inventory_line = inventory.lines.new(product=product)
+ >>> inventory_line.quantity = 100.0
+ >>> inventory_line.expected_quantity = 0.0
+ >>> inventory.click('confirm')
+ >>> inventory.state
+ 'done'
+
+Create needs for tomorrow in second warehouse::
+
+ >>> ShipmentOut = Model.get('stock.shipment.out')
+ >>> shipment = ShipmentOut()
+ >>> shipment.planned_date = tomorrow
+ >>> shipment.customer = customer
+ >>> shipment.warehouse = sec_warehouse_loc
+ >>> move = shipment.outgoing_moves.new()
+ >>> move.product = product
+ >>> move.quantity = 10
+ >>> move.from_location = sec_warehouse_loc.output_location
+ >>> move.to_location = customer_loc
+ >>> move.unit_price = Decimal('20')
+ >>> move.currency = company.currency
+ >>> shipment.click('wait')
+ >>> shipment.state
+ 'waiting'
+
+Execute internal supply::
+
+ >>> ShipmentInternal = Model.get('stock.shipment.internal')
+ >>> Wizard('stock.supply').execute('create_')
+ >>> shipments = ShipmentInternal.find([], order=[('planned_date', 'ASC')])
+ >>> len(shipments)
+ 2
+ >>> first, second = shipments
+
+ >>> first.planned_date == today
+ True
+ >>> first.state
+ 'request'
+ >>> len(first.moves)
+ 1
+ >>> move, = first.moves
+ >>> move.from_location == warehouse_loc.storage_location
+ True
+ >>> move.to_location == sec_warehouse_loc.storage_location
+ True
+ >>> move.quantity
+ 15.0
+
+ >>> second.planned_date == tomorrow
+ True
+ >>> second.state
+ 'request'
+ >>> len(second.moves)
+ 1
+ >>> move, = second.moves
+ >>> move.from_location == warehouse_loc.storage_location
+ True
+ >>> move.to_location == sec_warehouse_loc.storage_location
+ True
+ >>> move.quantity
+ 10.0
diff --git a/modules/stock_supply/tests/scenario_stock_internal_supply_overflow.rst b/modules/stock_supply/tests/scenario_stock_internal_supply_overflow.rst
new file mode 100644
index 0000000000..a8e427b5d5
--- /dev/null
+++ b/modules/stock_supply/tests/scenario_stock_internal_supply_overflow.rst
@@ -0,0 +1,145 @@
+====================================================
+Stock supply scenario: Internal supply with overflow
+====================================================
+
+Imports::
+
+ >>> import datetime
+ >>> from dateutil.relativedelta import relativedelta
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> today = datetime.date.today()
+
+Activate modules::
+
+ >>> config = activate_modules('stock_supply')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template.save()
+ >>> product, = template.products
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+ >>> lost_loc, = Location.find([('type', '=', 'lost_found')])
+
+Using order point to control the overflow
+-----------------------------------------
+
+Create the overflow location::
+
+ >>> overflow_loc = Location()
+ >>> overflow_loc.name = 'Overflow Location'
+ >>> overflow_loc.type = 'storage'
+ >>> overflow_loc.parent = warehouse_loc
+ >>> overflow_loc.save()
+
+Create the overflowed location::
+
+ >>> overflowed_storage_loc = Location()
+ >>> overflowed_storage_loc.name = 'Overflowed Location'
+ >>> overflowed_storage_loc.type = 'storage'
+ >>> overflowed_storage_loc.parent = warehouse_loc
+ >>> overflowed_storage_loc.save()
+
+Create an internal order point::
+
+ >>> OrderPoint = Model.get('stock.order_point')
+ >>> overflow_order_point = OrderPoint()
+ >>> overflow_order_point.product = product
+ >>> overflow_order_point.storage_location = overflowed_storage_loc
+ >>> overflow_order_point.overflowing_location = overflow_loc
+ >>> overflow_order_point.type = 'internal'
+ >>> overflow_order_point.max_quantity = 80
+ >>> overflow_order_point.target_quantity = 60
+ >>> overflow_order_point.save()
+
+Put too much quantity in the overflowed location::
+
+ >>> Move = Model.get('stock.move')
+ >>> move = Move()
+ >>> move.product = product
+ >>> move.quantity = 100
+ >>> move.from_location = lost_loc
+ >>> move.to_location = overflowed_storage_loc
+ >>> move.click('do')
+
+Execute internal supply::
+
+ >>> ShipmentInternal = Model.get('stock.shipment.internal')
+ >>> Wizard('stock.supply').execute('create_')
+ >>> shipment, = ShipmentInternal.find([
+ ... ('to_location', '=', overflow_loc.id),
+ ... ])
+ >>> shipment.state
+ 'request'
+ >>> move, = shipment.moves
+ >>> move.product.id == product.id
+ True
+ >>> move.quantity
+ 40.0
+ >>> move.from_location.id == overflowed_storage_loc.id
+ True
+ >>> move.to_location.id == overflow_loc.id
+ True
+
+Using an overflow location
+--------------------------
+
+Create the overflowed location::
+
+ >>> sec_overflowed_storage_loc = Location()
+ >>> sec_overflowed_storage_loc.name = 'Second Overflowed Location'
+ >>> sec_overflowed_storage_loc.type = 'storage'
+ >>> sec_overflowed_storage_loc.parent = warehouse_loc
+ >>> sec_overflowed_storage_loc.overflowing_location = overflow_loc
+ >>> sec_overflowed_storage_loc.save()
+
+Create positive quantity in this location::
+
+ >>> move = Move()
+ >>> move.product = product
+ >>> move.quantity = 10
+ >>> move.from_location = lost_loc
+ >>> move.to_location = sec_overflowed_storage_loc
+ >>> move.click('do')
+
+Execute internal supply::
+
+ >>> Wizard('stock.supply').execute('create_')
+ >>> shipment, = ShipmentInternal.find(
+ ... [('from_location', '=', sec_overflowed_storage_loc.id)])
+ >>> shipment.state
+ 'request'
+ >>> move, = shipment.moves
+ >>> move.product.id == product.id
+ True
+ >>> move.quantity
+ 10.0
+ >>> move.from_location.id == sec_overflowed_storage_loc.id
+ True
+ >>> move.to_location.id == overflow_loc.id
+ True
diff --git a/modules/stock_supply/tests/scenario_stock_supply_purchase_request.rst b/modules/stock_supply/tests/scenario_stock_supply_purchase_request.rst
new file mode 100644
index 0000000000..0244427d38
--- /dev/null
+++ b/modules/stock_supply/tests/scenario_stock_supply_purchase_request.rst
@@ -0,0 +1,252 @@
+=========================
+Purchase Request Scenario
+=========================
+
+Imports::
+
+ >>> import datetime
+ >>> from dateutil.relativedelta import relativedelta
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules, set_user
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> from trytond.modules.account.tests.tools import (create_chart,
+ ... get_accounts)
+ >>> today = datetime.date.today()
+
+Activate modules::
+
+ >>> config = activate_modules('stock_supply')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create chart of accounts::
+
+ >>> _ = create_chart(company)
+ >>> accounts = get_accounts(company)
+ >>> expense = accounts['expense']
+
+Create parties::
+
+ >>> Party = Model.get('party.party')
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+ >>> supplier = Party(name='Supplier')
+ >>> supplier.save()
+
+Configure supply period::
+
+ >>> PurchaseConfig = Model.get('purchase.configuration')
+ >>> purchase_config = PurchaseConfig(1)
+ >>> purchase_config.supply_period = datetime.timedelta(days=30)
+ >>> purchase_config.save()
+
+Create stock admin user::
+
+ >>> User = Model.get('res.user')
+ >>> Group = Model.get('res.group')
+ >>> stock_admin_user = User()
+ >>> stock_admin_user.name = 'Stock Admin'
+ >>> stock_admin_user.login = 'stock_admin'
+ >>> stock_admin_group, = Group.find([('name', '=', 'Stock Administration')])
+ >>> stock_admin_user.groups.append(stock_admin_group)
+ >>> stock_admin_user.save()
+
+Create stock user::
+
+ >>> stock_user = User()
+ >>> stock_user.name = 'Stock'
+ >>> stock_user.login = 'stock'
+ >>> stock_group, = Group.find([('name', '=', 'Stock')])
+ >>> stock_user.groups.append(stock_group)
+ >>> stock_user.save()
+
+Create product user::
+
+ >>> product_admin_user = User()
+ >>> product_admin_user.name = 'Product'
+ >>> product_admin_user.login = 'product'
+ >>> product_admin_group, = Group.find([
+ ... ('name', '=', 'Account Product Administration'),
+ ... ])
+ >>> product_admin_user.groups.append(product_admin_group)
+ >>> product_admin_user.save()
+
+Create purchase user::
+
+ >>> purchase_user = User()
+ >>> purchase_user.name = 'Purchase'
+ >>> purchase_user.login = 'purchase'
+ >>> purchase_groups = Group.find(['OR',
+ ... ('name', '=', "Purchase"),
+ ... ('name', '=', "Purchase Request"),
+ ... ])
+ >>> purchase_user.groups.extend(purchase_groups)
+ >>> purchase_user.save()
+
+
+Create account category::
+
+ >>> ProductCategory = Model.get('product.category')
+ >>> account_category = ProductCategory(name="Account Category")
+ >>> account_category.accounting = True
+ >>> account_category.account_expense = expense
+ >>> account_category.save()
+
+Create product::
+
+ >>> set_user(product_admin_user)
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template.purchasable = True
+ >>> template.account_category = account_category
+ >>> template.save()
+ >>> product, = template.products
+
+Define a product supplier::
+
+ >>> set_user(purchase_user)
+ >>> ProductSupplier = Model.get('purchase.product_supplier')
+ >>> product_supplier = ProductSupplier(template=template)
+ >>> product_supplier.party = supplier
+ >>> product_supplier.lead_time = datetime.timedelta(days=1)
+ >>> product_supplier.save()
+
+Get stock locations::
+
+ >>> set_user(stock_admin_user)
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> supplier_loc, = Location.find([('code', '=', 'SUP')])
+ >>> customer_loc, = Location.find([('code', '=', 'CUS')])
+ >>> output_loc, = Location.find([('code', '=', 'OUT')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+
+Create needs for missing product::
+
+ >>> set_user(stock_user)
+ >>> ShipmentOut = Model.get('stock.shipment.out')
+ >>> shipment_out = ShipmentOut()
+ >>> shipment_out.planned_date = today
+ >>> shipment_out.effective_date = today
+ >>> shipment_out.customer = customer
+ >>> shipment_out.warehouse = warehouse_loc
+ >>> shipment_out.company = company
+ >>> move = shipment_out.outgoing_moves.new()
+ >>> move.product = product
+ >>> move.uom = unit
+ >>> move.quantity = 1
+ >>> move.from_location = output_loc
+ >>> move.to_location = customer_loc
+ >>> move.company = company
+ >>> move.unit_price = Decimal('1')
+ >>> move.currency = company.currency
+ >>> shipment_out.click('wait')
+
+ >>> shipment_out, = shipment_out.duplicate(
+ ... default={'planned_date': today + datetime.timedelta(days=10)})
+ >>> shipment_out.click('wait')
+
+There is no purchase request::
+
+ >>> PurchaseRequest = Model.get('purchase.request')
+ >>> set_user(purchase_user)
+ >>> PurchaseRequest.find([])
+ []
+
+Create the purchase request::
+
+ >>> set_user(stock_admin_user)
+ >>> create_pr = Wizard('stock.supply')
+ >>> create_pr.execute('create_')
+
+There is now a draft purchase request::
+
+ >>> set_user(purchase_user)
+ >>> pr, = PurchaseRequest.find([('state', '=', 'draft')])
+ >>> pr.product == product
+ True
+ >>> pr.quantity
+ 2.0
+
+Create an order point with negative minimal quantity::
+
+ >>> set_user(stock_admin_user)
+ >>> OrderPoint = Model.get('stock.order_point')
+ >>> order_point = OrderPoint()
+ >>> order_point.type = 'purchase'
+ >>> order_point.product = product
+ >>> order_point.warehouse_location = warehouse_loc
+ >>> order_point.min_quantity = -2
+ >>> order_point.target_quantity = 10
+ >>> order_point.save()
+
+Create purchase request::
+
+ >>> create_pr = Wizard('stock.supply')
+ >>> create_pr.execute('create_')
+
+There is no more purchase request::
+
+ >>> set_user(purchase_user)
+ >>> PurchaseRequest.find([])
+ []
+
+Set a positive minimal quantity on order point create purchase request::
+
+ >>> set_user(stock_admin_user)
+ >>> order_point.min_quantity = 5
+ >>> order_point.save()
+ >>> create_pr = Wizard('stock.supply')
+ >>> create_pr.execute('create_')
+
+There is now a draft purchase request::
+
+ >>> set_user(purchase_user)
+ >>> pr, = PurchaseRequest.find([('state', '=', 'draft')])
+ >>> pr.product == product
+ True
+ >>> pr.quantity
+ 12.0
+
+Using zero as minimal quantity on order point also creates purchase request::
+
+ >>> set_user(stock_admin_user)
+ >>> order_point.min_quantity = 0
+ >>> order_point.save()
+ >>> create_pr = Wizard('stock.supply')
+ >>> create_pr.execute('create_')
+
+There is now a draft purchase request::
+
+ >>> set_user(purchase_user)
+ >>> pr, = PurchaseRequest.find([('state', '=', 'draft')])
+ >>> pr.product == product
+ True
+ >>> pr.quantity
+ 12.0
+
+Re-run with purchased request::
+
+ >>> create_purchase = Wizard('purchase.request.create_purchase', [pr])
+ >>> pr.state
+ 'purchased'
+
+ >>> set_user(stock_admin_user)
+ >>> create_pr = Wizard('stock.supply')
+ >>> create_pr.execute('create_')
+
+ >>> set_user(purchase_user)
+ >>> len(PurchaseRequest.find([('state', '=', 'draft')]))
+ 0
diff --git a/modules/stock_supply/tests/test_module.py b/modules/stock_supply/tests/test_module.py
new file mode 100644
index 0000000000..5e841cf4e4
--- /dev/null
+++ b/modules/stock_supply/tests/test_module.py
@@ -0,0 +1,159 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import datetime
+
+from trytond.modules.account.tests import create_chart
+from trytond.modules.company.tests import (
+ CompanyTestMixin, create_company, set_company)
+from trytond.pool import Pool
+from trytond.tests.test_tryton import ModuleTestCase, with_transaction
+
+DATES = [
+ # purchase date, lead time, supply date
+ (datetime.date(2011, 11, 21), datetime.timedelta(10),
+ datetime.date(2011, 12, 1)),
+ (datetime.date(2011, 11, 21), datetime.timedelta(9),
+ datetime.date(2011, 11, 30)),
+ (datetime.date(2011, 11, 21), datetime.timedelta(8),
+ datetime.date(2011, 11, 29)),
+ (datetime.date(2011, 11, 21), datetime.timedelta(7),
+ datetime.date(2011, 11, 28)),
+ (datetime.date(2011, 11, 21), datetime.timedelta(6),
+ datetime.date(2011, 11, 27)),
+ (datetime.date(2011, 11, 21), datetime.timedelta(5),
+ datetime.date(2011, 11, 26)),
+ (datetime.date(2011, 11, 21), datetime.timedelta(4),
+ datetime.date(2011, 11, 25)),
+ ]
+
+
+class StockSupplyTestCase(CompanyTestMixin, ModuleTestCase):
+ 'Test StockSupply module'
+ module = 'stock_supply'
+
+ def test_compute_supply_date(self):
+ 'Test compute_supply_date'
+ @with_transaction()
+ def run(purchase_date, lead_time, supply_date):
+ pool = Pool()
+ ProductSupplier = pool.get('purchase.product_supplier')
+ product_supplier = self.create_product_supplier(lead_time)
+ date = ProductSupplier.compute_supply_date(
+ product_supplier, purchase_date)
+ self.assertEqual(date, supply_date)
+ for purchase_date, lead_time, supply_date in DATES:
+ run(purchase_date, lead_time, supply_date)
+
+ def test_compute_purchase_date(self):
+ 'Test compute_purchase_date'
+ @with_transaction()
+ def run(purchase_date, lead_time, supply_date):
+ pool = Pool()
+ ProductSupplier = pool.get('purchase.product_supplier')
+ product_supplier = self.create_product_supplier(lead_time)
+ date = ProductSupplier.compute_purchase_date(
+ product_supplier, supply_date)
+ self.assertEqual(date, purchase_date)
+ for purchase_date, lead_time, supply_date in DATES:
+ run(purchase_date, lead_time, supply_date)
+
+ def create_product_supplier(self, lead_time):
+ '''
+ Create a Product with a Product Supplier
+
+ :param lead_time: timedelta needed to supply
+ :return: the id of the Product Supplier
+ '''
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ UomCategory = pool.get('product.uom.category')
+ Template = pool.get('product.template')
+ Product = pool.get('product.product')
+ Party = pool.get('party.party')
+ Account = pool.get('account.account')
+ ProductSupplier = pool.get('purchase.product_supplier')
+
+ uom_category, = UomCategory.create([{'name': 'Test'}])
+ uom, = Uom.create([{
+ 'name': 'Test',
+ 'symbol': 'T',
+ 'category': uom_category.id,
+ 'rate': 1.0,
+ 'factor': 1.0,
+ }])
+ template, = Template.create([{
+ 'name': 'ProductTest',
+ 'default_uom': uom.id,
+ }])
+ product, = Product.create([{
+ 'template': template.id,
+ }])
+ company = create_company()
+ with set_company(company):
+ create_chart(company)
+ receivable, = Account.search([
+ ('type.receivable', '=', True),
+ ('company', '=', company.id),
+ ])
+ payable, = Account.search([
+ ('type.payable', '=', True),
+ ('company', '=', company.id),
+ ])
+ supplier, = Party.create([{
+ 'name': 'supplier',
+ 'account_receivable': receivable.id,
+ 'account_payable': payable.id,
+ }])
+ product_supplier, = ProductSupplier.create([{
+ 'template': template.id,
+ 'company': company.id,
+ 'party': supplier.id,
+ 'lead_time': lead_time,
+ }])
+ return product_supplier
+
+ @with_transaction()
+ def test_order_point_location_searcher(self):
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ Template = pool.get('product.template')
+ Product = pool.get('product.product')
+ Location = pool.get('stock.location')
+ OrderPoint = pool.get('stock.order_point')
+ unit, = Uom.search([('symbol', '=', 'u')])
+ template, = Template.create([{
+ 'name': 'ProductTest',
+ 'type': 'goods',
+ 'default_uom': unit.id,
+ 'purchase_uom': unit.id,
+ 'purchasable': True,
+ }])
+ product, = Product.create([{
+ 'template': template.id,
+ }])
+
+ warehouse, = Location.search([('type', '=', 'warehouse')])
+ storage, = Location.search([('code', '=', 'STO')])
+
+ company = create_company()
+ with set_company(company):
+ order_point, = OrderPoint.create([{
+ 'product': product.id,
+ 'type': 'purchase',
+ 'warehouse_location': warehouse.id,
+ 'min_quantity': 0.0,
+ 'target_quantity': 5.0,
+ }])
+
+ for clause, result in [
+ (('location', '=', warehouse.name), [order_point]),
+ (('location', '=', 'storage'), []),
+ (('location', '!=', warehouse.name), []),
+ (('location', '!=', 'storage'), [order_point]),
+ ]:
+ self.assertListEqual(
+ OrderPoint.search(clause), result, msg=clause)
+
+
+del ModuleTestCase
diff --git a/modules/stock_supply/tests/test_scenario.py b/modules/stock_supply/tests/test_scenario.py
new file mode 100644
index 0000000000..dc1d23e7e5
--- /dev/null
+++ b/modules/stock_supply/tests/test_scenario.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import load_doc_tests
+
+
+def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_supply/tox.ini b/modules/stock_supply/tox.ini
new file mode 100644
index 0000000000..4f3af887d9
--- /dev/null
+++ b/modules/stock_supply/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_supply/* -m unittest discover -s tests
+ coverage report --include=./**/stock_supply/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_supply/tryton.cfg b/modules/stock_supply/tryton.cfg
new file mode 100644
index 0000000000..69d507d924
--- /dev/null
+++ b/modules/stock_supply/tryton.cfg
@@ -0,0 +1,18 @@
+[tryton]
+version=6.7.0
+depends:
+ account
+ ir
+ party
+ product
+ purchase
+ purchase_request
+ res
+ stock
+xml:
+ order_point.xml
+ purchase_request.xml
+ product.xml
+ location.xml
+ stock.xml
+ message.xml
diff --git a/modules/stock_supply/view/location_form.xml b/modules/stock_supply/view/location_form.xml
new file mode 100644
index 0000000000..d36218b2fe
--- /dev/null
+++ b/modules/stock_supply/view/location_form.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_supply/view/order_point_form.xml b/modules/stock_supply/view/order_point_form.xml
new file mode 100644
index 0000000000..2cf3c4bb88
--- /dev/null
+++ b/modules/stock_supply/view/order_point_form.xml
@@ -0,0 +1,28 @@
+
+
+
diff --git a/modules/stock_supply/view/order_point_tree.xml b/modules/stock_supply/view/order_point_tree.xml
new file mode 100644
index 0000000000..6da6fa778c
--- /dev/null
+++ b/modules/stock_supply/view/order_point_tree.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_supply/view/purchase_configuration_form.xml b/modules/stock_supply/view/purchase_configuration_form.xml
new file mode 100644
index 0000000000..e190744109
--- /dev/null
+++ b/modules/stock_supply/view/purchase_configuration_form.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_supply/view/supply_start_form.xml b/modules/stock_supply/view/supply_start_form.xml
new file mode 100644
index 0000000000..b7310246dc
--- /dev/null
+++ b/modules/stock_supply/view/supply_start_form.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/modules/stock_supply_day/.drone.yml b/modules/stock_supply_day/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_supply_day/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_supply_day/.flake8 b/modules/stock_supply_day/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_supply_day/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_supply_day/.isort.cfg b/modules/stock_supply_day/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_supply_day/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_supply_day/CHANGELOG b/modules/stock_supply_day/CHANGELOG
new file mode 100644
index 0000000000..bf5c8dfb9c
--- /dev/null
+++ b/modules/stock_supply_day/CHANGELOG
@@ -0,0 +1,91 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+* Use multiselection for days
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+* Use ir.calendar.day
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+
+Version 4.2.0 - 2016-11-28
+* Bug fixes (see mercurial logs for details)
+
+Version 4.0.0 - 2016-05-02
+* Bug fixes (see mercurial logs for details)
+* Add Python3 support
+
+Version 3.8.0 - 2015-11-02
+* Bug fixes (see mercurial logs for details)
+
+Version 3.6.0 - 2015-04-20
+* Bug fixes (see mercurial logs for details)
+* Add support for PyPy
+Version 3.4.0 - 2014-10-20
+* Bug fixes (see mercurial logs for details)
+
+Version 3.2.0 - 2014-04-21
+* Bug fixes (see mercurial logs for details)
+
+Version 3.0.0 - 2013-10-21
+* Bug fixes (see mercurial logs for details)
+
+Version 2.8.0 - 2013-04-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.6.0 - 2012-10-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.4.0 - 2012-04-24
+* Bug fixes (see mercurial logs for details)
+
+Version 2.2.0 - 2011-10-25
+* Bug fixes (see mercurial logs for details)
+
+Version 2.0.0 - 2011-04-27
+* Bug fixes (see mercurial logs for details)
+
+Version 1.8.0 - 2010-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 1.6.0 - 2010-05-13
+* Bug fixes (see mercurial logs for details)
+
+Version 1.4.0 - 2009-10-19
+* Bug fixes (see mercurial logs for details)
+
+Version 1.2.0 - 2009-07-31
+* Initial release
diff --git a/modules/stock_supply_day/COPYRIGHT b/modules/stock_supply_day/COPYRIGHT
new file mode 100644
index 0000000000..068e2b6331
--- /dev/null
+++ b/modules/stock_supply_day/COPYRIGHT
@@ -0,0 +1,16 @@
+Copyright (C) 2008-2022 Cédric Krier.
+Copyright (C) 2008-2012 Bertrand Chenal.
+Copyright (C) 2008-2022 B2CK SPRL.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_supply_day/LICENSE b/modules/stock_supply_day/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_supply_day/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_supply_day/MANIFEST.in b/modules/stock_supply_day/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_supply_day/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_supply_day/README.rst b/modules/stock_supply_day/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_supply_day/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_supply_day/__init__.py b/modules/stock_supply_day/__init__.py
new file mode 100644
index 0000000000..ce1eed4c23
--- /dev/null
+++ b/modules/stock_supply_day/__init__.py
@@ -0,0 +1,13 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import purchase
+
+
+def register():
+ Pool.register(
+ purchase.ProductSupplier,
+ purchase.ProductSupplierDay,
+ module='stock_supply_day', type_='model')
diff --git a/modules/stock_supply_day/doc/index.rst b/modules/stock_supply_day/doc/index.rst
new file mode 100644
index 0000000000..9291e95a0c
--- /dev/null
+++ b/modules/stock_supply_day/doc/index.rst
@@ -0,0 +1,12 @@
+Stock Supply Day Module
+#######################
+
+The Stock Supply Day module adds a Week Days list on the Product
+Supplier form. This allow to restrict the supply week days for each
+supplier on each product. If no days are defined for a supplier a
+supplying may happens at any day of the week.
+
+For example, those week days are taken into account when computing the
+planned date of stock moves created by the purchase (defined in the
+Purchase module) and by the scheduler that generates the Purchase
+Requests (defined in the Stock Supply module).
diff --git a/modules/stock_supply_day/locale/bg.po b/modules/stock_supply_day/locale/bg.po
new file mode 100644
index 0000000000..04aa377a98
--- /dev/null
+++ b/modules/stock_supply_day/locale/bg.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "Дни от седмицата"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Доставчик"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr "Ден на доставчик на наличност"
diff --git a/modules/stock_supply_day/locale/ca.po b/modules/stock_supply_day/locale/ca.po
new file mode 100644
index 0000000000..2ffdd918a9
--- /dev/null
+++ b/modules/stock_supply_day/locale/ca.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "Dies de la setmana"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr "Dia"
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Proveïdor"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr "Dia del proveïdor del producte"
diff --git a/modules/stock_supply_day/locale/cs.po b/modules/stock_supply_day/locale/cs.po
new file mode 100644
index 0000000000..5993b908e0
--- /dev/null
+++ b/modules/stock_supply_day/locale/cs.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr ""
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr ""
diff --git a/modules/stock_supply_day/locale/de.po b/modules/stock_supply_day/locale/de.po
new file mode 100644
index 0000000000..791b408f3d
--- /dev/null
+++ b/modules/stock_supply_day/locale/de.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "Wochentage"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr "Tag"
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Lieferant"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr "Lieferant Tag"
diff --git a/modules/stock_supply_day/locale/es.po b/modules/stock_supply_day/locale/es.po
new file mode 100644
index 0000000000..211ac97755
--- /dev/null
+++ b/modules/stock_supply_day/locale/es.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "Días de la semana"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr "Día"
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Proveedor"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr "Día del proveedor del producto"
diff --git a/modules/stock_supply_day/locale/es_419.po b/modules/stock_supply_day/locale/es_419.po
new file mode 100644
index 0000000000..5993b908e0
--- /dev/null
+++ b/modules/stock_supply_day/locale/es_419.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr ""
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr ""
diff --git a/modules/stock_supply_day/locale/et.po b/modules/stock_supply_day/locale/et.po
new file mode 100644
index 0000000000..fe469787f5
--- /dev/null
+++ b/modules/stock_supply_day/locale/et.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "Nädalapäevad"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr "Päev"
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Hankija"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr "Toote hankija päev"
diff --git a/modules/stock_supply_day/locale/fa.po b/modules/stock_supply_day/locale/fa.po
new file mode 100644
index 0000000000..32399efad6
--- /dev/null
+++ b/modules/stock_supply_day/locale/fa.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "روزهای هفته"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "تأمین کننده"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr "روز عرضه محصولات"
diff --git a/modules/stock_supply_day/locale/fi.po b/modules/stock_supply_day/locale/fi.po
new file mode 100644
index 0000000000..5993b908e0
--- /dev/null
+++ b/modules/stock_supply_day/locale/fi.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr ""
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr ""
diff --git a/modules/stock_supply_day/locale/fr.po b/modules/stock_supply_day/locale/fr.po
new file mode 100644
index 0000000000..b23eede9a5
--- /dev/null
+++ b/modules/stock_supply_day/locale/fr.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "Jours de la semaine"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr "Jour"
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Fournisseur"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr "Journée du fournisseur de produit"
diff --git a/modules/stock_supply_day/locale/hu.po b/modules/stock_supply_day/locale/hu.po
new file mode 100644
index 0000000000..f42d142d04
--- /dev/null
+++ b/modules/stock_supply_day/locale/hu.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "Hét napjai"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr "Nap"
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Szállító"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr "Terméket szállító nap"
diff --git a/modules/stock_supply_day/locale/id.po b/modules/stock_supply_day/locale/id.po
new file mode 100644
index 0000000000..02e84da4eb
--- /dev/null
+++ b/modules/stock_supply_day/locale/id.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr "Hari"
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Pemasok"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr ""
diff --git a/modules/stock_supply_day/locale/it.po b/modules/stock_supply_day/locale/it.po
new file mode 100644
index 0000000000..1b7c446ebc
--- /dev/null
+++ b/modules/stock_supply_day/locale/it.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "Giorni della settimana"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr "Giorno"
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Fornitore"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr "Giornata del fornitore del prodotto"
diff --git a/modules/stock_supply_day/locale/lo.po b/modules/stock_supply_day/locale/lo.po
new file mode 100644
index 0000000000..6ddaf7f4a5
--- /dev/null
+++ b/modules/stock_supply_day/locale/lo.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "ວັນໃນອາທິດ"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "ຜູ້ສະໜອງ"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr "ມື້ສະໜອງຜະລິດຕະພັນ"
diff --git a/modules/stock_supply_day/locale/lt.po b/modules/stock_supply_day/locale/lt.po
new file mode 100644
index 0000000000..5993b908e0
--- /dev/null
+++ b/modules/stock_supply_day/locale/lt.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr ""
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr ""
diff --git a/modules/stock_supply_day/locale/nl.po b/modules/stock_supply_day/locale/nl.po
new file mode 100644
index 0000000000..68b2e3ef21
--- /dev/null
+++ b/modules/stock_supply_day/locale/nl.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "Weekdagen"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr "Dag"
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Leverancier"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr "Leveranciersdag"
diff --git a/modules/stock_supply_day/locale/pl.po b/modules/stock_supply_day/locale/pl.po
new file mode 100644
index 0000000000..0411e82199
--- /dev/null
+++ b/modules/stock_supply_day/locale/pl.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "Dni tygodnia"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Dostawca"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr ""
diff --git a/modules/stock_supply_day/locale/pt.po b/modules/stock_supply_day/locale/pt.po
new file mode 100644
index 0000000000..d237c84ec2
--- /dev/null
+++ b/modules/stock_supply_day/locale/pt.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "Dias da semana"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Fornecedor"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr "Dia do fornecedor do produto"
diff --git a/modules/stock_supply_day/locale/ro.po b/modules/stock_supply_day/locale/ro.po
new file mode 100644
index 0000000000..fa6a79c22b
--- /dev/null
+++ b/modules/stock_supply_day/locale/ro.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "Zile Săptămânii"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr "Ziua"
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Furnizor"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr "Produs Furnizor Zi"
diff --git a/modules/stock_supply_day/locale/ru.po b/modules/stock_supply_day/locale/ru.po
new file mode 100644
index 0000000000..2e08107aad
--- /dev/null
+++ b/modules/stock_supply_day/locale/ru.po
@@ -0,0 +1,21 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "День недели"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Поставщик"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr ""
diff --git a/modules/stock_supply_day/locale/sl.po b/modules/stock_supply_day/locale/sl.po
new file mode 100644
index 0000000000..bb05a78cd6
--- /dev/null
+++ b/modules/stock_supply_day/locale/sl.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr "Dnevi v tednu"
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Dobavitelj"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr "Dobaviteljev dan"
diff --git a/modules/stock_supply_day/locale/tr.po b/modules/stock_supply_day/locale/tr.po
new file mode 100644
index 0000000000..bf200abf07
--- /dev/null
+++ b/modules/stock_supply_day/locale/tr.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr "Tedarikçi"
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr "Ürün Tedarikçi Günü"
diff --git a/modules/stock_supply_day/locale/uk.po b/modules/stock_supply_day/locale/uk.po
new file mode 100644
index 0000000000..5993b908e0
--- /dev/null
+++ b/modules/stock_supply_day/locale/uk.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr ""
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr ""
diff --git a/modules/stock_supply_day/locale/zh_CN.po b/modules/stock_supply_day/locale/zh_CN.po
new file mode 100644
index 0000000000..5993b908e0
--- /dev/null
+++ b/modules/stock_supply_day/locale/zh_CN.po
@@ -0,0 +1,19 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:purchase.product_supplier,weekdays:"
+msgid "Week Days"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,day:"
+msgid "Day"
+msgstr ""
+
+msgctxt "field:purchase.product_supplier.day,product_supplier:"
+msgid "Supplier"
+msgstr ""
+
+msgctxt "model:purchase.product_supplier.day,name:"
+msgid "Product Supplier Day"
+msgstr ""
diff --git a/modules/stock_supply_day/purchase.py b/modules/stock_supply_day/purchase.py
new file mode 100644
index 0000000000..772cffe594
--- /dev/null
+++ b/modules/stock_supply_day/purchase.py
@@ -0,0 +1,72 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import datetime
+
+from trytond.model import ModelSQL, fields
+from trytond.pool import Pool, PoolMeta
+from trytond.transaction import Transaction
+
+
+class ProductSupplier(metaclass=PoolMeta):
+ __name__ = 'purchase.product_supplier'
+ weekdays = fields.Many2Many(
+ 'purchase.product_supplier.day', 'product_supplier', 'day',
+ "Week Days")
+
+ def compute_supply_date(self, date=None):
+ date = super(ProductSupplier, self).compute_supply_date(date=date)
+ earlier_date = None
+ if date != datetime.date.max:
+ for weekday in self.weekdays:
+ diff = weekday.index - date.weekday()
+ if diff < 0:
+ diff += 7
+ new_date = date + datetime.timedelta(diff)
+
+ if earlier_date and earlier_date <= new_date:
+ continue
+ earlier_date = new_date
+ return earlier_date or date
+
+ def compute_purchase_date(self, date):
+ later_date = None
+ for weekday in self.weekdays:
+ diff = (date.weekday() - weekday.index) % 7
+ new_date = date - datetime.timedelta(diff)
+ if later_date and later_date >= new_date:
+ continue
+ later_date = new_date
+ if later_date:
+ date = later_date
+ return super(ProductSupplier, self).compute_purchase_date(date)
+
+
+class ProductSupplierDay(ModelSQL):
+ 'Product Supplier Day'
+ __name__ = 'purchase.product_supplier.day'
+ product_supplier = fields.Many2One(
+ 'purchase.product_supplier', 'Supplier',
+ required=True, ondelete='CASCADE')
+ day = fields.Many2One('ir.calendar.day', "Day", required=True)
+
+ @classmethod
+ def __register__(cls, module_name):
+ pool = Pool()
+ Day = pool.get('ir.calendar.day')
+ day = Day.__table__()
+ transaction = Transaction()
+ table = cls.__table__()
+
+ super().__register__(module_name)
+ table_h = cls.__table_handler__(module_name)
+
+ # Migration from 5.0: replace weekday by day
+ if table_h.column_exist('weekday'):
+ cursor = transaction.connection.cursor()
+ update = transaction.connection.cursor()
+ cursor.execute(*day.select(day.id, day.index))
+ for day_id, index in cursor:
+ update.execute(*table.update(
+ [table.day], [day_id],
+ where=table.weekday == str(index)))
+ table_h.drop_column('weekday')
diff --git a/modules/stock_supply_day/purchase.xml b/modules/stock_supply_day/purchase.xml
new file mode 100644
index 0000000000..542be0be3c
--- /dev/null
+++ b/modules/stock_supply_day/purchase.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ purchase.product_supplier
+
+ product_supplier_form
+
+
+
diff --git a/modules/stock_supply_day/setup.py b/modules/stock_supply_day/setup.py
new file mode 100755
index 0000000000..62ff9b2db9
--- /dev/null
+++ b/modules/stock_supply_day/setup.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_supply_day'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = []
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module to add supply weekdays',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_supply_day',
+ },
+ keywords='tryton supply day',
+ package_dir={'trytond.modules.stock_supply_day': '.'},
+ packages=(
+ ['trytond.modules.stock_supply_day']
+ + ['trytond.modules.stock_supply_day.%s' % p for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_supply_day': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Legal Industry',
+ 'Intended Audience :: Manufacturing',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_supply_day = trytond.modules.stock_supply_day
+ """,
+ )
diff --git a/modules/stock_supply_day/tests/__init__.py b/modules/stock_supply_day/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_supply_day/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_supply_day/tests/test_module.py b/modules/stock_supply_day/tests/test_module.py
new file mode 100644
index 0000000000..7bd8742014
--- /dev/null
+++ b/modules/stock_supply_day/tests/test_module.py
@@ -0,0 +1,154 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import datetime
+
+from trytond.modules.account.tests import create_chart
+from trytond.modules.company.tests import (
+ CompanyTestMixin, create_company, set_company)
+from trytond.pool import Pool
+from trytond.tests.test_tryton import ModuleTestCase, with_transaction
+
+
+class StockSupplyDayTestCase(CompanyTestMixin, ModuleTestCase):
+ 'Test StockSupplyDay module'
+ module = 'stock_supply_day'
+
+ def test_compute_supply_date(self):
+ 'Test compute_supply_date'
+ dates = [
+ # purchase date, lead time, weekday, supply date
+ (datetime.date(2011, 11, 21), datetime.timedelta(10), 0,
+ datetime.date(2011, 12, 5)),
+ (datetime.date(2011, 11, 21), datetime.timedelta(9), 1,
+ datetime.date(2011, 12, 6)),
+ (datetime.date(2011, 11, 21), datetime.timedelta(8), 2,
+ datetime.date(2011, 11, 30)),
+ (datetime.date(2011, 11, 21), datetime.timedelta(7), 3,
+ datetime.date(2011, 12, 1)),
+ (datetime.date(2011, 11, 21), datetime.timedelta(6), 4,
+ datetime.date(2011, 12, 2)),
+ (datetime.date(2011, 11, 21), datetime.timedelta(5), 5,
+ datetime.date(2011, 11, 26)),
+ (datetime.date(2011, 11, 21), datetime.timedelta(4), 6,
+ datetime.date(2011, 11, 27)),
+ (datetime.date(2011, 12, 22), datetime.timedelta(12), 6,
+ datetime.date(2012, 1, 8)),
+ (datetime.date(2011, 11, 21), datetime.timedelta(10), None,
+ datetime.date(2011, 12, 1)),
+ (datetime.date(2011, 11, 21), None, 0, datetime.date.max),
+ ]
+ # Purchase date is Monday, 2011-11-21, the regular days to deliver is
+ # 10 days, which would be Wednesday 2011-12-01. But with the supplier
+ # weekday 0 (Monday) the forecast supply date is next Monday, the
+ # 2011-12-05.
+
+ @with_transaction()
+ def run(purchase_date, lead_time, weekday, supply_date):
+ product_supplier = self.create_product_supplier_day(
+ lead_time, weekday)
+ date = product_supplier.compute_supply_date(purchase_date)
+ self.assertEqual(date, supply_date)
+ for purchase_date, lead_time, weekday, supply_date in dates:
+ run(purchase_date, lead_time, weekday, supply_date)
+
+ def test_compute_purchase_date(self):
+ 'Test compute_purchase_date'
+ dates = [
+ # purchase date, lead time, weekday, supply date
+ (datetime.date(2011, 11, 25), datetime.timedelta(10), 0,
+ datetime.date(2011, 12, 6)),
+ (datetime.date(2011, 11, 27), datetime.timedelta(9), 1,
+ datetime.date(2011, 12, 6)),
+ (datetime.date(2011, 11, 22), datetime.timedelta(8), 2,
+ datetime.date(2011, 12, 6)),
+ (datetime.date(2011, 11, 24), datetime.timedelta(7), 3,
+ datetime.date(2011, 12, 6)),
+ (datetime.date(2011, 11, 26), datetime.timedelta(6), 4,
+ datetime.date(2011, 12, 6)),
+ (datetime.date(2011, 11, 28), datetime.timedelta(5), 5,
+ datetime.date(2011, 12, 6)),
+ (datetime.date(2011, 11, 30), datetime.timedelta(4), 6,
+ datetime.date(2011, 12, 6)),
+ (datetime.date(2011, 12, 27), datetime.timedelta(6), 0,
+ datetime.date(2012, 1, 3)),
+ ]
+ # Supply date max is Tuesday, 2012-01-03, the supplier weekday 0 which
+ # would be Monday 2012-01-02. But with the 6 days of delivery the
+ # forecast purchase date is the 2011-12-27.
+
+ @with_transaction()
+ def run(purchase_date, lead_time, weekday, supply_date):
+ product_supplier = self.create_product_supplier_day(
+ lead_time, weekday)
+ date = product_supplier.compute_purchase_date(supply_date)
+ self.assertEqual(date, purchase_date)
+ for purchase_date, lead_time, weekday, supply_date in dates:
+ run(purchase_date, lead_time, weekday, supply_date)
+
+ def create_product_supplier_day(self, lead_time, weekday):
+ '''
+ Create a Product with a Product Supplier Day
+
+ :param lead_time: minimal timedelta needed to supply
+ :param weekday: supply day of the week (0 - 6)
+ :return: the id of the Product Supplier Day
+ '''
+ pool = Pool()
+ Uom = pool.get('product.uom')
+ UomCategory = pool.get('product.uom.category')
+ Template = pool.get('product.template')
+ Product = pool.get('product.product')
+ Party = pool.get('party.party')
+ Account = pool.get('account.account')
+ ProductSupplier = pool.get('purchase.product_supplier')
+ ProductSupplierDay = pool.get('purchase.product_supplier.day')
+ Day = pool.get('ir.calendar.day')
+
+ uom_category, = UomCategory.create([{'name': 'Test'}])
+ uom, = Uom.create([{
+ 'name': 'Test',
+ 'symbol': 'T',
+ 'category': uom_category.id,
+ 'rate': 1.0,
+ 'factor': 1.0,
+ }])
+ template, = Template.create([{
+ 'name': 'ProductTest',
+ 'default_uom': uom.id,
+ }])
+ product, = Product.create([{
+ 'template': template.id,
+ }])
+ company = create_company()
+ with set_company(company):
+ create_chart(company)
+ receivable, = Account.search([
+ ('type.receivable', '=', True),
+ ('company', '=', company.id),
+ ])
+ payable, = Account.search([
+ ('type.payable', '=', True),
+ ('company', '=', company.id),
+ ])
+ supplier, = Party.create([{
+ 'name': 'supplier',
+ 'account_receivable': receivable.id,
+ 'account_payable': payable.id,
+ }])
+ product_supplier, = ProductSupplier.create([{
+ 'template': template.id,
+ 'company': company.id,
+ 'party': supplier.id,
+ 'lead_time': lead_time,
+ }])
+ if weekday is not None:
+ day, = Day.search([('index', '=', weekday)])
+ ProductSupplierDay.create([{
+ 'product_supplier': product_supplier.id,
+ 'day': day.id,
+ }])
+ return product_supplier
+
+
+del ModuleTestCase
diff --git a/modules/stock_supply_day/tox.ini b/modules/stock_supply_day/tox.ini
new file mode 100644
index 0000000000..b18be9fddb
--- /dev/null
+++ b/modules/stock_supply_day/tox.ini
@@ -0,0 +1,16 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+commands =
+ coverage run --include=./**/stock_supply_day/* -m unittest discover -s tests
+ coverage report --include=./**/stock_supply_day/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_supply_day/tryton.cfg b/modules/stock_supply_day/tryton.cfg
new file mode 100644
index 0000000000..4efb62c545
--- /dev/null
+++ b/modules/stock_supply_day/tryton.cfg
@@ -0,0 +1,7 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ purchase
+xml:
+ purchase.xml
diff --git a/modules/stock_supply_day/view/product_supplier_form.xml b/modules/stock_supply_day/view/product_supplier_form.xml
new file mode 100644
index 0000000000..111fdc684f
--- /dev/null
+++ b/modules/stock_supply_day/view/product_supplier_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/stock_supply_forecast/.drone.yml b/modules/stock_supply_forecast/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_supply_forecast/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_supply_forecast/.flake8 b/modules/stock_supply_forecast/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_supply_forecast/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_supply_forecast/.isort.cfg b/modules/stock_supply_forecast/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_supply_forecast/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_supply_forecast/CHANGELOG b/modules/stock_supply_forecast/CHANGELOG
new file mode 100644
index 0000000000..f3878ead5b
--- /dev/null
+++ b/modules/stock_supply_forecast/CHANGELOG
@@ -0,0 +1,75 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Setup forecast for all supplies
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+
+Version 4.2.0 - 2016-11-28
+* Bug fixes (see mercurial logs for details)
+
+Version 4.0.0 - 2016-05-02
+* Bug fixes (see mercurial logs for details)
+* Add Python3 support
+
+Version 3.8.0 - 2015-11-02
+* Bug fixes (see mercurial logs for details)
+
+Version 3.6.0 - 2015-04-20
+* Bug fixes (see mercurial logs for details)
+* Add support for PyPy
+Version 3.4.0 - 2014-10-20
+* Bug fixes (see mercurial logs for details)
+
+Version 3.2.0 - 2014-04-21
+* Bug fixes (see mercurial logs for details)
+
+Version 3.0.0 - 2013-10-21
+* Bug fixes (see mercurial logs for details)
+
+Version 2.8.0 - 2013-04-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.6.0 - 2012-10-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.4.0 - 2012-04-24
+* Bug fixes (see mercurial logs for details)
+
+Version 2.2.0 - 2011-10-25
+* Initial release
diff --git a/modules/stock_supply_forecast/COPYRIGHT b/modules/stock_supply_forecast/COPYRIGHT
new file mode 100644
index 0000000000..51a574630e
--- /dev/null
+++ b/modules/stock_supply_forecast/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2011-2022 Cédric Krier.
+Copyright (C) 2011-2022 B2CK SPRL.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_supply_forecast/LICENSE b/modules/stock_supply_forecast/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_supply_forecast/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_supply_forecast/MANIFEST.in b/modules/stock_supply_forecast/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_supply_forecast/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_supply_forecast/README.rst b/modules/stock_supply_forecast/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_supply_forecast/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_supply_forecast/__init__.py b/modules/stock_supply_forecast/__init__.py
new file mode 100644
index 0000000000..78dd684cf9
--- /dev/null
+++ b/modules/stock_supply_forecast/__init__.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import stock
+
+
+def register():
+ Pool.register(
+ stock.Supply,
+ module='stock_supply_forecast', type_='wizard')
diff --git a/modules/stock_supply_forecast/doc/index.rst b/modules/stock_supply_forecast/doc/index.rst
new file mode 100644
index 0000000000..eb3b0e20d7
--- /dev/null
+++ b/modules/stock_supply_forecast/doc/index.rst
@@ -0,0 +1,5 @@
+Stock Supply Forecast Module
+############################
+
+The stock supply forecast module takes forecast into account to compute
+purchase requests.
diff --git a/modules/stock_supply_forecast/setup.py b/modules/stock_supply_forecast/setup.py
new file mode 100755
index 0000000000..fc31619bfc
--- /dev/null
+++ b/modules/stock_supply_forecast/setup.py
@@ -0,0 +1,151 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_supply_forecast'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = []
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [get_require_version('proteus')]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module to add forecast to supply computation',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_supply_forecast',
+ },
+ keywords='tryton stock supply forecast',
+ package_dir={'trytond.modules.stock_supply_forecast': '.'},
+ packages=(
+ ['trytond.modules.stock_supply_forecast']
+ + ['trytond.modules.stock_supply_forecast.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_supply_forecast': (info.get('xml', [])
+ + ['tryton.cfg', 'locale/*.po', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'Intended Audience :: Manufacturing',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_supply_forecast = trytond.modules.stock_supply_forecast
+ """,
+ )
diff --git a/modules/stock_supply_forecast/stock.py b/modules/stock_supply_forecast/stock.py
new file mode 100644
index 0000000000..cb16c71aeb
--- /dev/null
+++ b/modules/stock_supply_forecast/stock.py
@@ -0,0 +1,23 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.pool import Pool, PoolMeta
+
+
+class Supply(metaclass=PoolMeta):
+ __name__ = 'stock.supply'
+
+ def transition_create_(self):
+ pool = Pool()
+ Forecast = pool.get('stock.forecast')
+ Date = pool.get('ir.date')
+
+ today = Date.today()
+
+ forecasts = Forecast.search([
+ ('to_date', '>=', today),
+ ('state', '=', 'done'),
+ ])
+ Forecast.create_moves(forecasts)
+ transition = super().transition_create_()
+ Forecast.delete_moves(forecasts)
+ return transition
diff --git a/modules/stock_supply_forecast/tests/__init__.py b/modules/stock_supply_forecast/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_supply_forecast/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_supply_forecast/tests/scenario_stock_supply_forecast.rst b/modules/stock_supply_forecast/tests/scenario_stock_supply_forecast.rst
new file mode 100644
index 0000000000..70022e5778
--- /dev/null
+++ b/modules/stock_supply_forecast/tests/scenario_stock_supply_forecast.rst
@@ -0,0 +1,101 @@
+==============================
+Stock Supply Forecast Scenario
+==============================
+
+Imports::
+
+ >>> import datetime
+ >>> from dateutil.relativedelta import relativedelta
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> from trytond.modules.account.tests.tools import (create_chart,
+ ... get_accounts)
+ >>> today = datetime.date.today()
+ >>> yesterday = today - relativedelta(days=1)
+ >>> tomorrow = today + relativedelta(days=1)
+
+Activate modules::
+
+ >>> config = activate_modules('stock_supply_forecast')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create chart of accounts::
+
+ >>> _ = create_chart(company)
+ >>> accounts = get_accounts(company)
+ >>> expense = accounts['expense']
+
+Create parties::
+
+ >>> Party = Model.get('party.party')
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+ >>> supplier = Party(name='Supplier')
+ >>> supplier.save()
+
+Create account category::
+
+ >>> ProductCategory = Model.get('product.category')
+ >>> account_category = ProductCategory(name="Account Category")
+ >>> account_category.accounting = True
+ >>> account_category.account_expense = expense
+ >>> account_category.save()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> ProductTemplate = Model.get('product.template')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'Product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.list_price = Decimal('20')
+ >>> template.purchasable = True
+ >>> template.account_category = account_category
+ >>> template.save()
+ >>> product, = template.products
+
+Get warehouse location::
+
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+
+Create a forecast::
+
+ >>> Forecast = Model.get('stock.forecast')
+ >>> forecast = Forecast()
+ >>> forecast.warehouse = warehouse_loc
+ >>> forecast.from_date = yesterday
+ >>> forecast.to_date = tomorrow
+ >>> forecast_line = forecast.lines.new()
+ >>> forecast_line.product = product
+ >>> forecast_line.quantity = 10
+ >>> forecast.save()
+
+There is no purchase request::
+
+ >>> create_pr = Wizard('stock.supply')
+ >>> create_pr.execute('create_')
+ >>> PurchaseRequest = Model.get('purchase.request')
+ >>> PurchaseRequest.find([])
+ []
+
+There is a draft purchase request after confirming the forecast::
+
+ >>> forecast.click('confirm')
+ >>> create_pr = Wizard('stock.supply')
+ >>> create_pr.execute('create_')
+ >>> pr, = PurchaseRequest.find([('state', '=', 'draft')])
+ >>> pr.product == product
+ True
+ >>> pr.quantity
+ 10.0
diff --git a/modules/stock_supply_forecast/tests/test_module.py b/modules/stock_supply_forecast/tests/test_module.py
new file mode 100644
index 0000000000..f449b3a738
--- /dev/null
+++ b/modules/stock_supply_forecast/tests/test_module.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockSupplyForecastTestCase(ModuleTestCase):
+ 'Test StockSupplyForecast module'
+ module = 'stock_supply_forecast'
+
+
+del ModuleTestCase
diff --git a/modules/stock_supply_forecast/tests/test_scenario.py b/modules/stock_supply_forecast/tests/test_scenario.py
new file mode 100644
index 0000000000..dc1d23e7e5
--- /dev/null
+++ b/modules/stock_supply_forecast/tests/test_scenario.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import load_doc_tests
+
+
+def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_supply_forecast/tox.ini b/modules/stock_supply_forecast/tox.ini
new file mode 100644
index 0000000000..637e9fdcbd
--- /dev/null
+++ b/modules/stock_supply_forecast/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_supply_forecast/* -m unittest discover -s tests
+ coverage report --include=./**/stock_supply_forecast/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_supply_forecast/tryton.cfg b/modules/stock_supply_forecast/tryton.cfg
new file mode 100644
index 0000000000..ad7e7f8b3f
--- /dev/null
+++ b/modules/stock_supply_forecast/tryton.cfg
@@ -0,0 +1,6 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ stock_supply
+ stock_forecast
diff --git a/modules/stock_supply_production/.drone.yml b/modules/stock_supply_production/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/stock_supply_production/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/stock_supply_production/.flake8 b/modules/stock_supply_production/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/stock_supply_production/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/stock_supply_production/.isort.cfg b/modules/stock_supply_production/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/stock_supply_production/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/stock_supply_production/CHANGELOG b/modules/stock_supply_production/CHANGELOG
new file mode 100644
index 0000000000..135940a442
--- /dev/null
+++ b/modules/stock_supply_production/CHANGELOG
@@ -0,0 +1,76 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+* Merge supply into one wizard
+* Do not create production request if other order point exists
+
+Version 4.2.0 - 2016-11-28
+* Bug fixes (see mercurial logs for details)
+
+Version 4.0.0 - 2016-05-02
+* Bug fixes (see mercurial logs for details)
+* Add Python3 support
+
+Version 3.8.0 - 2015-11-02
+* Bug fixes (see mercurial logs for details)
+
+Version 3.6.0 - 2015-04-20
+* Bug fixes (see mercurial logs for details)
+* Add support for PyPy
+* Add warning for late production when creating production request.
+
+Version 3.4.0 - 2014-10-20
+* Bug fixes (see mercurial logs for details)
+* Allow to calculate production requests filtered by warehouse
+
+Version 3.2.0 - 2014-04-21
+* Bug fixes (see mercurial logs for details)
+
+Version 3.0.0 - 2013-10-21
+* Bug fixes (see mercurial logs for details)
+
+Version 2.8.0 - 2013-04-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.6.0 - 2012-10-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.4.0 - 2012-08-15
+* Initial release
diff --git a/modules/stock_supply_production/COPYRIGHT b/modules/stock_supply_production/COPYRIGHT
new file mode 100644
index 0000000000..03f4719f79
--- /dev/null
+++ b/modules/stock_supply_production/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2012-2022 Cédric Krier.
+Copyright (C) 2012-2022 B2CK SPRL.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/stock_supply_production/LICENSE b/modules/stock_supply_production/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/stock_supply_production/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/stock_supply_production/MANIFEST.in b/modules/stock_supply_production/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/stock_supply_production/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/stock_supply_production/README.rst b/modules/stock_supply_production/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/stock_supply_production/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/stock_supply_production/__init__.py b/modules/stock_supply_production/__init__.py
new file mode 100644
index 0000000000..e5df0d9cf1
--- /dev/null
+++ b/modules/stock_supply_production/__init__.py
@@ -0,0 +1,20 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import product, production, stock
+
+
+def register():
+ Pool.register(
+ stock.OrderPoint,
+ stock.LocationLeadTime,
+ production.Configuration,
+ production.ConfigurationSupplyPeriod,
+ production.Production,
+ product.Product,
+ module='stock_supply_production', type_='model')
+ Pool.register(
+ stock.StockSupply,
+ module='stock_supply_production', type_='wizard')
diff --git a/modules/stock_supply_production/doc/index.rst b/modules/stock_supply_production/doc/index.rst
new file mode 100644
index 0000000000..c09c4954b1
--- /dev/null
+++ b/modules/stock_supply_production/doc/index.rst
@@ -0,0 +1,27 @@
+Stock Supply Production Module
+##############################
+
+The Stock Supply Production module adds automatic supply mechanisms via
+production request.
+
+Production Request
+******************
+
+A production request is a production in the state request. It defines the need
+to produce a product.
+
+
+Order Point
+***********
+
+It adds a new type of Order Point:
+
+* Production
+
+ A Production order point is defined on a warehouse location. If the minimal
+ quantity is reached at any time on the warehouse it will result in a
+ production request.
+
+The production requests are created by the supply wizard with respect to stock
+levels and existing requests. The stock levels are computed on the supply
+period define in the production configuration.
diff --git a/modules/stock_supply_production/locale/bg.po b/modules/stock_supply_production/locale/bg.po
new file mode 100644
index 0000000000..9302d95332
--- /dev/null
+++ b/modules/stock_supply_production/locale/bg.po
@@ -0,0 +1,34 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Request Productions"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Управление на производство"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr ""
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Управление на производство"
diff --git a/modules/stock_supply_production/locale/ca.po b/modules/stock_supply_production/locale/ca.po
new file mode 100644
index 0000000000..27fd06dfe6
--- /dev/null
+++ b/modules/stock_supply_production/locale/ca.po
@@ -0,0 +1,32 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Període de subministre"
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Període de subministre"
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Sol·licituds de producció"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Producció"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr "Hi ha algunes produccions endarrerides."
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr "Configuració del període de subministre de la producció"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Producció"
diff --git a/modules/stock_supply_production/locale/cs.po b/modules/stock_supply_production/locale/cs.po
new file mode 100644
index 0000000000..f6ad374dc8
--- /dev/null
+++ b/modules/stock_supply_production/locale/cs.po
@@ -0,0 +1,33 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Request Productions"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr ""
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Production"
diff --git a/modules/stock_supply_production/locale/de.po b/modules/stock_supply_production/locale/de.po
new file mode 100644
index 0000000000..42f415213f
--- /dev/null
+++ b/modules/stock_supply_production/locale/de.po
@@ -0,0 +1,32 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Beschaffungszeitraum"
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Beschaffungszeitraum"
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Produktionsaufträge anfordern"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Produktion"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr "Einige Produktionsaufträge sind verspätet."
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr "Einstellungen Produktion Beschaffungszeitraum"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Produktion"
diff --git a/modules/stock_supply_production/locale/es.po b/modules/stock_supply_production/locale/es.po
new file mode 100644
index 0000000000..1dda4efb22
--- /dev/null
+++ b/modules/stock_supply_production/locale/es.po
@@ -0,0 +1,32 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Periodo de suministro"
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Periodo de suministro"
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Solicitudes de producción"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Producción"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr "Hay algunas producciones retrasadas."
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr "Configuración del periodo de subministro de la producción"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Producción"
diff --git a/modules/stock_supply_production/locale/es_419.po b/modules/stock_supply_production/locale/es_419.po
new file mode 100644
index 0000000000..89090c62b2
--- /dev/null
+++ b/modules/stock_supply_production/locale/es_419.po
@@ -0,0 +1,32 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr ""
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr ""
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr ""
diff --git a/modules/stock_supply_production/locale/et.po b/modules/stock_supply_production/locale/et.po
new file mode 100644
index 0000000000..3571c40292
--- /dev/null
+++ b/modules/stock_supply_production/locale/et.po
@@ -0,0 +1,32 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Tarneaeg"
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Tarneaeg"
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Tootmiste päring"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Tootmine"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr "Osad tooted hilinevad."
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr "Tootmise seadistus tarneaeg"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Tootmine"
diff --git a/modules/stock_supply_production/locale/fa.po b/modules/stock_supply_production/locale/fa.po
new file mode 100644
index 0000000000..9444459661
--- /dev/null
+++ b/modules/stock_supply_production/locale/fa.po
@@ -0,0 +1,32 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "دوره عرضه"
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "دوره عرضه"
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "درخواست تولیدات"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "تولید"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr "برخی از محصولات تأخیر دارند."
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr "پیکربندی تولید ؛ دوره عرضه"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "تولید"
diff --git a/modules/stock_supply_production/locale/fi.po b/modules/stock_supply_production/locale/fi.po
new file mode 100644
index 0000000000..f6ad374dc8
--- /dev/null
+++ b/modules/stock_supply_production/locale/fi.po
@@ -0,0 +1,33 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Request Productions"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr ""
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Production"
diff --git a/modules/stock_supply_production/locale/fr.po b/modules/stock_supply_production/locale/fr.po
new file mode 100644
index 0000000000..dcb6503012
--- /dev/null
+++ b/modules/stock_supply_production/locale/fr.po
@@ -0,0 +1,32 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Période d'approvisionnement"
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Période d'approvisionnement"
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Demandes de production"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr "Il y a des productions qui sont en retard."
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr "Configuration production période d'approvisionnement"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Production"
diff --git a/modules/stock_supply_production/locale/hu.po b/modules/stock_supply_production/locale/hu.po
new file mode 100644
index 0000000000..d5d5e29d4b
--- /dev/null
+++ b/modules/stock_supply_production/locale/hu.po
@@ -0,0 +1,35 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Beszerzési időszak"
+
+#, fuzzy
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Beszerzési időszak"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Request Productions"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr ""
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr ""
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Termelés"
diff --git a/modules/stock_supply_production/locale/id.po b/modules/stock_supply_production/locale/id.po
new file mode 100644
index 0000000000..245e22600a
--- /dev/null
+++ b/modules/stock_supply_production/locale/id.po
@@ -0,0 +1,32 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Produksi"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr "Ada beberapa produksi yang terlambat."
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr "Periode Pasokan Konfigurasi Produksi"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Produksi"
diff --git a/modules/stock_supply_production/locale/it.po b/modules/stock_supply_production/locale/it.po
new file mode 100644
index 0000000000..7e24c533be
--- /dev/null
+++ b/modules/stock_supply_production/locale/it.po
@@ -0,0 +1,32 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Periodo di fornitura"
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Periodo di fornitura"
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Request Productions"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr "Ci sono alcune produzioni che sono in ritardo."
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr ""
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Produzione"
diff --git a/modules/stock_supply_production/locale/lo.po b/modules/stock_supply_production/locale/lo.po
new file mode 100644
index 0000000000..3acdd87707
--- /dev/null
+++ b/modules/stock_supply_production/locale/lo.po
@@ -0,0 +1,34 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "ໄລຍະສະໜອງ"
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "ໄລຍະສະໜອງ"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Request Productions"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr ""
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr "ໄລຍະກຳນົດການສະໜອງຜະລິດຕະພັນ"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "ການຜະລິດ"
diff --git a/modules/stock_supply_production/locale/lt.po b/modules/stock_supply_production/locale/lt.po
new file mode 100644
index 0000000000..f6ad374dc8
--- /dev/null
+++ b/modules/stock_supply_production/locale/lt.po
@@ -0,0 +1,33 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Request Productions"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr ""
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Production"
diff --git a/modules/stock_supply_production/locale/nl.po b/modules/stock_supply_production/locale/nl.po
new file mode 100644
index 0000000000..ee157efb45
--- /dev/null
+++ b/modules/stock_supply_production/locale/nl.po
@@ -0,0 +1,32 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Leveringstermijn"
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Leveringstermijn"
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Vraag productie aan"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Productie"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr "Er zijn enkele producties die laat zijn."
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr "Productieconfiguratie Leveringsperiode"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Productie"
diff --git a/modules/stock_supply_production/locale/pl.po b/modules/stock_supply_production/locale/pl.po
new file mode 100644
index 0000000000..dfab04d2f5
--- /dev/null
+++ b/modules/stock_supply_production/locale/pl.po
@@ -0,0 +1,33 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Request Productions"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr ""
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr ""
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Produkcja"
diff --git a/modules/stock_supply_production/locale/pt.po b/modules/stock_supply_production/locale/pt.po
new file mode 100644
index 0000000000..0406e755bf
--- /dev/null
+++ b/modules/stock_supply_production/locale/pt.po
@@ -0,0 +1,34 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Período de Abastecimento"
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Período de Abastecimento"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Request Productions"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr ""
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr "Configurações de Produção Período de Abastecimento"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Produção"
diff --git a/modules/stock_supply_production/locale/ro.po b/modules/stock_supply_production/locale/ro.po
new file mode 100644
index 0000000000..89090c62b2
--- /dev/null
+++ b/modules/stock_supply_production/locale/ro.po
@@ -0,0 +1,32 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr ""
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr ""
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr ""
diff --git a/modules/stock_supply_production/locale/ru.po b/modules/stock_supply_production/locale/ru.po
new file mode 100644
index 0000000000..a716b697aa
--- /dev/null
+++ b/modules/stock_supply_production/locale/ru.po
@@ -0,0 +1,34 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Request Productions"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Производство"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr ""
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Производство"
diff --git a/modules/stock_supply_production/locale/sl.po b/modules/stock_supply_production/locale/sl.po
new file mode 100644
index 0000000000..c661417a63
--- /dev/null
+++ b/modules/stock_supply_production/locale/sl.po
@@ -0,0 +1,34 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr "Obdobje dobave"
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr "Obdobje dobave"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Request Productions"
+
+#, fuzzy
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr ""
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr "Konfiguracija obdobja dobave proizvodnje"
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Proizvodni nalog"
diff --git a/modules/stock_supply_production/locale/tr.po b/modules/stock_supply_production/locale/tr.po
new file mode 100644
index 0000000000..f6ad374dc8
--- /dev/null
+++ b/modules/stock_supply_production/locale/tr.po
@@ -0,0 +1,33 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Request Productions"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr ""
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Production"
diff --git a/modules/stock_supply_production/locale/uk.po b/modules/stock_supply_production/locale/uk.po
new file mode 100644
index 0000000000..89090c62b2
--- /dev/null
+++ b/modules/stock_supply_production/locale/uk.po
@@ -0,0 +1,32 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr ""
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr ""
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr ""
+
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr ""
diff --git a/modules/stock_supply_production/locale/zh_CN.po b/modules/stock_supply_production/locale/zh_CN.po
new file mode 100644
index 0000000000..f6ad374dc8
--- /dev/null
+++ b/modules/stock_supply_production/locale/zh_CN.po
@@ -0,0 +1,33 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:production.configuration,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "field:production.configuration.supply_period,supply_period:"
+msgid "Supply Period"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_production_request"
+msgid "Request Productions"
+msgstr "Request Productions"
+
+msgctxt ""
+"model:ir.action.act_window.domain,name:act_order_point_form_domain_production"
+msgid "Production"
+msgstr "Production"
+
+msgctxt "model:ir.message,text:msg_late_productions"
+msgid "There are some productions that are late."
+msgstr ""
+
+msgctxt "model:production.configuration.supply_period,name:"
+msgid "Production Configuration Supply Period"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:stock.order_point,type:"
+msgid "Production"
+msgstr "Production"
diff --git a/modules/stock_supply_production/message.xml b/modules/stock_supply_production/message.xml
new file mode 100644
index 0000000000..d934b5eb3f
--- /dev/null
+++ b/modules/stock_supply_production/message.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+ There are some productions that are late.
+
+
+
diff --git a/modules/stock_supply_production/product.py b/modules/stock_supply_production/product.py
new file mode 100644
index 0000000000..71706f7da5
--- /dev/null
+++ b/modules/stock_supply_production/product.py
@@ -0,0 +1,15 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from datetime import timedelta
+
+from trytond.pool import Pool, PoolMeta
+
+
+class Product(metaclass=PoolMeta):
+ __name__ = 'product.product'
+
+ def get_supply_period(self):
+ 'Return the supply period for the product'
+ pool = Pool()
+ Configuration = pool.get('production.configuration')
+ return Configuration(1).supply_period or timedelta(0)
diff --git a/modules/stock_supply_production/production.py b/modules/stock_supply_production/production.py
new file mode 100644
index 0000000000..8862b75849
--- /dev/null
+++ b/modules/stock_supply_production/production.py
@@ -0,0 +1,246 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import datetime
+from collections import defaultdict
+
+from trytond.model import ModelSQL, ValueMixin, fields
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import TimeDelta
+from trytond.tools import grouped_slice
+from trytond.transaction import Transaction
+
+supply_period = fields.TimeDelta(
+ "Supply Period",
+ domain=['OR',
+ ('supply_period', '=', None),
+ ('supply_period', '>=', TimeDelta()),
+ ])
+
+
+class Configuration(metaclass=PoolMeta):
+ __name__ = 'production.configuration'
+ supply_period = fields.MultiValue(supply_period)
+
+
+class ConfigurationSupplyPeriod(ModelSQL, ValueMixin):
+ "Production Configuration Supply Period"
+ __name__ = 'production.configuration.supply_period'
+ supply_period = supply_period
+
+
+class Production(metaclass=PoolMeta):
+ __name__ = 'production'
+
+ @classmethod
+ def _get_origin(cls):
+ origins = super()._get_origin()
+ return origins | {'stock.order_point'}
+
+ @classmethod
+ def generate_requests(cls, clean=True, warehouses=None):
+ """
+ For each product compute the production request that must be created
+ today to meet product outputs.
+
+ If clean is set, it will remove all previous requests.
+
+ If warehouses is specified it will compute the production requests
+ only for the selected warehouses.
+ """
+ pool = Pool()
+ OrderPoint = pool.get('stock.order_point')
+ Product = pool.get('product.product')
+ Location = pool.get('stock.location')
+ Date = pool.get('ir.date')
+ User = pool.get('res.user')
+ company = User(Transaction().user).company
+
+ if clean:
+ reqs = cls.search([
+ ('state', '=', 'request'),
+ ('origin', 'like', 'stock.order_point,%'),
+ ])
+ if warehouses:
+ reqs = [r for r in reqs if r.warehouse in warehouses]
+ cls.delete(reqs)
+
+ if warehouses is None:
+ # fetch warehouse
+ warehouses = Location.search([
+ ('type', '=', 'warehouse'),
+ ])
+ warehouse_ids = [w.id for w in warehouses]
+ # fetch order points
+ order_points = OrderPoint.search([
+ ('warehouse_location', '!=', None),
+ ('company', '=', company.id if company else None),
+ ])
+ # index them by product
+ product2ops = {}
+ product2ops_other = {}
+ for order_point in order_points:
+ if order_point.type == 'production':
+ dict_ = product2ops
+ else:
+ dict_ = product2ops_other
+ dict_[
+ (order_point.warehouse_location.id, order_point.product.id)
+ ] = order_point
+
+ # fetch goods
+ products = Product.search([
+ ('type', '=', 'goods'),
+ ('consumable', '=', False),
+ ('producible', '=', True),
+ ])
+ # compute requests
+ today = Date.today()
+
+ # aggregate product by supply period
+ date2products = defaultdict(list)
+ for product in products:
+ min_date = today
+ max_date = today + product.get_supply_period()
+ date2products[min_date, max_date].append(product)
+
+ requests = []
+ for (min_date, max_date), dates_products in date2products.items():
+ for sub_products in grouped_slice(products):
+ sub_products = list(sub_products)
+ product_ids = [p.id for p in sub_products]
+ with Transaction().set_context(
+ forecast=True,
+ stock_date_end=min_date):
+ pbl = Product.products_by_location(
+ warehouse_ids,
+ with_childs=True,
+ grouping_filter=(product_ids,))
+
+ for warehouse in warehouses:
+ min_date_qties = defaultdict(int,
+ ((x, pbl.pop((warehouse.id, x), 0))
+ for x in product_ids))
+ # Do not compute shortage for product
+ # with different order point
+ product_ids = [
+ p.id for p in sub_products
+ if (warehouse.id, p.id) not in product2ops_other]
+ # Search for shortage between min-max
+ shortages = cls.get_shortage(
+ warehouse.id, product_ids, min_date, max_date,
+ min_date_qties=min_date_qties,
+ order_points=product2ops)
+
+ for product in sub_products:
+ if product.id not in shortages:
+ continue
+ for date, quantity in shortages[product.id]:
+ order_point = product2ops.get(
+ (warehouse.id, product.id))
+ req = cls.compute_request(product, warehouse,
+ quantity, date, company, order_point)
+ req.planned_start_date = (
+ req.on_change_with_planned_start_date())
+ requests.append(req)
+ cls.save(requests)
+ cls.set_moves(requests)
+ return requests
+
+ @classmethod
+ def compute_request(
+ cls, product, warehouse, quantity, date, company,
+ order_point=None):
+ """
+ Return the value of the production request.
+ """
+ pool = Pool()
+ Date = pool.get('ir.date')
+ with Transaction().set_context(company=company.id):
+ today = Date.today()
+ if date <= today:
+ date = today
+ else:
+ date -= datetime.timedelta(1)
+ uom = product.default_uom
+ quantity = uom.ceil(quantity)
+ if order_point:
+ origin = str(order_point)
+ else:
+ origin = 'stock.order_point,-1'
+ return cls(
+ planned_date=date,
+ company=company,
+ warehouse=warehouse,
+ location=warehouse.production_location,
+ product=product,
+ bom=product.boms[0].bom if product.boms else None,
+ uom=uom,
+ quantity=quantity,
+ state='request',
+ origin=origin,
+ )
+
+ @classmethod
+ def get_shortage(cls, location_id, product_ids, min_date, max_date,
+ min_date_qties, order_points):
+ """
+ Return for each product a list of dates where the stock quantity is
+ less than the minimal quantity and the quantity to reach the maximal
+ quantity over the period.
+
+ The minimal and maximal quantities come from the order point or are
+ zero.
+
+ min_date_qty is the quantities for each product at the min date.
+ order_points is a dictionary that links products to order points.
+ """
+ pool = Pool()
+ Product = pool.get('product.product')
+
+ shortages = defaultdict(list)
+ min_quantities = defaultdict(float)
+ target_quantities = defaultdict(float)
+ for product_id in product_ids:
+ order_point = order_points.get((location_id, product_id))
+ if order_point:
+ min_quantities[product_id] = order_point.min_quantity
+ target_quantities[product_id] = order_point.target_quantity
+
+ with Transaction().set_context(
+ forecast=True,
+ stock_date_start=min_date,
+ stock_date_end=max_date):
+ pbl = Product.products_by_location(
+ [location_id],
+ with_childs=True,
+ grouping=('date', 'product'),
+ grouping_filter=(None, product_ids))
+ pbl_dates = defaultdict(dict)
+ for key, qty in pbl.items():
+ date, product_id = key[1:]
+ pbl_dates[date][product_id] = qty
+
+ current_date = min_date
+ current_qties = min_date_qties.copy()
+ products_to_check = product_ids.copy()
+ while (current_date < max_date) or (current_date == min_date):
+ for product_id in products_to_check:
+ current_qty = current_qties[product_id]
+ min_quantity = min_quantities[product_id]
+ if min_quantity is not None and current_qty < min_quantity:
+ target_quantity = target_quantities[product_id]
+ quantity = target_quantity - current_qty
+ shortages[product_id].append((current_date, quantity))
+ current_qties[product_id] += quantity
+
+ if current_date == datetime.date.max:
+ break
+ current_date += datetime.timedelta(1)
+
+ pbl = pbl_dates[current_date]
+ products_to_check.clear()
+ for product_id, qty in pbl.items():
+ current_qties[product_id] += qty
+ products_to_check.append(product_id)
+
+ return shortages
diff --git a/modules/stock_supply_production/production.xml b/modules/stock_supply_production/production.xml
new file mode 100644
index 0000000000..381ea47765
--- /dev/null
+++ b/modules/stock_supply_production/production.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+ production.configuration
+
+ production_configuration_form
+
+
+
+ Request Productions
+ production
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/stock_supply_production/setup.py b/modules/stock_supply_production/setup.py
new file mode 100755
index 0000000000..b0971f101e
--- /dev/null
+++ b/modules/stock_supply_production/setup.py
@@ -0,0 +1,151 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_stock_supply_production'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = []
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [get_require_version('proteus')]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module for stock supply of production',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/stock_supply_production',
+ },
+ keywords='tryton stock supply production',
+ package_dir={'trytond.modules.stock_supply_production': '.'},
+ packages=(
+ ['trytond.modules.stock_supply_production']
+ + ['trytond.modules.stock_supply_production.%s' % p
+ for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.stock_supply_production': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'Intended Audience :: Manufacturing',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ stock_supply_production = trytond.modules.stock_supply_production
+ """,
+ )
diff --git a/modules/stock_supply_production/stock.py b/modules/stock_supply_production/stock.py
new file mode 100644
index 0000000000..b8c02da385
--- /dev/null
+++ b/modules/stock_supply_production/stock.py
@@ -0,0 +1,108 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import datetime
+
+from trytond.i18n import gettext
+from trytond.modules.stock_supply.exceptions import SupplyWarning
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Eval, If
+from trytond.wizard import StateAction
+
+
+class OrderPoint(metaclass=PoolMeta):
+ __name__ = 'stock.order_point'
+
+ @classmethod
+ def __setup__(cls):
+ super(OrderPoint, cls).__setup__()
+
+ cls.product.domain = [
+ cls.product.domain,
+ If(Eval('type') == 'production',
+ ('producible', '=', True),
+ ()),
+ ]
+
+ cls.warehouse_location.states['invisible'] &= (
+ Eval('type') != 'production')
+ cls.warehouse_location.states['required'] |= (
+ Eval('type') == 'production')
+
+ option = ('production', 'Production')
+ if option not in cls.type.selection:
+ cls.type.selection.append(option)
+
+ @classmethod
+ def _type2field(cls, type=None):
+ if type == 'production':
+ return 'warehouse_location'
+ result = super(OrderPoint, cls)._type2field(type=type)
+ if type is None:
+ result['production'] = 'warehouse_location'
+ return result
+
+ def get_location(self, name):
+ location = super(OrderPoint, self).get_location(name)
+ if self.type == 'production':
+ return self.warehouse_location.id
+ return location
+
+
+class LocationLeadTime(metaclass=PoolMeta):
+ __name__ = 'stock.location.lead_time'
+
+ @classmethod
+ def _get_extra_lead_times(cls):
+ pool = Pool()
+ Configuration = pool.get('production.configuration')
+ config = Configuration(1)
+ supply_period = config.get_multivalue('supply_period')
+ extra = super(LocationLeadTime, cls)._get_extra_lead_times()
+ extra.append(supply_period or datetime.timedelta(0))
+ return extra
+
+
+class StockSupply(metaclass=PoolMeta):
+ __name__ = 'stock.supply'
+
+ production = StateAction('stock_supply_production.act_production_request')
+
+ @classmethod
+ def types(cls):
+ return super(StockSupply, cls).types() + ['production']
+
+ def transition_create_(self):
+ pool = Pool()
+ Date = pool.get('ir.date')
+ Move = pool.get('stock.move')
+ Warning = pool.get('res.user.warning')
+ today = Date.today()
+ if Move.search([
+ ('from_location.type', '=', 'production'),
+ ('to_location.type', '=', 'storage'),
+ ('state', '=', 'draft'),
+ ('planned_date', '<', today),
+ ], order=[]):
+ key = '%s@%s' % (self.__name__, today)
+ if Warning.check(key):
+ raise SupplyWarning(
+ key,
+ gettext('stock_supply_production.msg_late_productions'))
+ return super(StockSupply, self).transition_create_()
+
+ @property
+ def _production_parameters(self):
+ parameters = {}
+ # Use getattr because start is empty when run by cron
+ if getattr(self.start, 'warehouses', None):
+ parameters['warehouses'] = self.start.warehouses
+ return parameters
+
+ def generate_production(self, clean):
+ pool = Pool()
+ Production = pool.get('production')
+ return Production.generate_requests(
+ clean=clean, **self._production_parameters)
+
+ def transition_production(self):
+ return self.next_action('production')
diff --git a/modules/stock_supply_production/stock.xml b/modules/stock_supply_production/stock.xml
new file mode 100644
index 0000000000..60ff5b7355
--- /dev/null
+++ b/modules/stock_supply_production/stock.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ Production
+
+
+
+
+
+
diff --git a/modules/stock_supply_production/tests/__init__.py b/modules/stock_supply_production/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/stock_supply_production/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/stock_supply_production/tests/scenario_stock_supply_production.rst b/modules/stock_supply_production/tests/scenario_stock_supply_production.rst
new file mode 100644
index 0000000000..7beffa6641
--- /dev/null
+++ b/modules/stock_supply_production/tests/scenario_stock_supply_production.rst
@@ -0,0 +1,157 @@
+===========================
+Production Request Scenario
+===========================
+
+Imports::
+
+ >>> import datetime as dt
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> from trytond.modules.stock.exceptions import MoveFutureWarning
+ >>> today = dt.date.today()
+
+Activate modules::
+
+ >>> config = activate_modules('stock_supply_production')
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+ >>> ProductTemplate = Model.get('product.template')
+
+ >>> template = ProductTemplate()
+ >>> template.name = 'product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.producible = True
+ >>> template.list_price = Decimal(30)
+ >>> template.save()
+ >>> product, = template.products
+
+Define a supply period for production::
+
+ >>> ProductionConfiguration = Model.get('production.configuration')
+ >>> production_configuration = ProductionConfiguration(1)
+ >>> production_configuration.supply_period = dt.timedelta(days=30)
+ >>> production_configuration.save()
+
+Get stock locations::
+
+ >>> Location = Model.get('stock.location')
+ >>> warehouse_loc, = Location.find([('code', '=', 'WH')])
+ >>> storage_loc, = Location.find([('code', '=', 'STO')])
+ >>> lost_loc, = Location.find([('type', '=', 'lost_found')])
+
+Create needs for product::
+
+ >>> Move = Model.get('stock.move')
+ >>> move = Move()
+ >>> move.product = product
+ >>> move.quantity = 1
+ >>> move.from_location = storage_loc
+ >>> move.to_location = lost_loc
+ >>> move.click('do')
+ >>> move.state
+ 'done'
+
+ >>> move, = move.duplicate(
+ ... default={'effective_date': today + dt.timedelta(days=10)})
+ >>> try:
+ ... move.click('do')
+ ... except MoveFutureWarning as warning:
+ ... _, (key, *_) = warning.args
+
+ >>> Warning = Model.get('res.user.warning')
+ >>> Warning(user=config.user, name=key).save()
+ >>> move.click('do')
+
+The is no production request::
+
+ >>> Production = Model.get('production')
+ >>> Production.find([])
+ []
+
+Create production request::
+
+ >>> create_pr = Wizard('stock.supply')
+ >>> create_pr.execute('create_')
+
+There is now a production request::
+
+ >>> productions = Production.find([])
+ >>> len(productions)
+ 2
+ >>> {p.state for p in productions}
+ {'request'}
+ >>> all(p.product == product for p in productions)
+ True
+ >>> sum(p.quantity for p in productions)
+ 2.0
+ >>> sorted(p.planned_date for p in productions) == [
+ ... today, today + dt.timedelta(days=9)]
+ True
+
+Create an order point negative minimal quantity::
+
+ >>> OrderPoint = Model.get('stock.order_point')
+ >>> order_point = OrderPoint()
+ >>> order_point.type = 'production'
+ >>> order_point.product = product
+ >>> order_point.warehouse_location = warehouse_loc
+ >>> order_point.min_quantity = -2
+ >>> order_point.target_quantity = 10
+ >>> order_point.save()
+
+Create production request::
+
+ >>> create_pr = Wizard('stock.supply')
+ >>> create_pr.execute('create_')
+
+The is no more production request::
+
+ >>> Production = Model.get('production')
+ >>> Production.find([])
+ []
+
+Set a minimal quantity on order point::
+
+ >>> order_point.min_quantity = 5
+ >>> order_point.save()
+
+Create production request::
+
+ >>> create_pr = Wizard('stock.supply')
+ >>> create_pr.execute('create_')
+
+There is now a production request::
+
+ >>> production, = Production.find([])
+ >>> production.state
+ 'request'
+ >>> production.product == product
+ True
+ >>> production.quantity
+ 11.0
+
+Using zero as minimal quantity also creates a production request::
+
+ >>> order_point.min_quantity = 0
+ >>> order_point.save()
+ >>> create_pr = Wizard('stock.supply')
+ >>> create_pr.execute('create_')
+ >>> production, = Production.find([])
+ >>> production.state
+ 'request'
+ >>> production.product == product
+ True
+ >>> production.quantity
+ 11.0
diff --git a/modules/stock_supply_production/tests/test_module.py b/modules/stock_supply_production/tests/test_module.py
new file mode 100644
index 0000000000..41c114d0a5
--- /dev/null
+++ b/modules/stock_supply_production/tests/test_module.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class StockSupplyProductionTestCase(ModuleTestCase):
+ 'Test Stock Supply Production module'
+ module = 'stock_supply_production'
+
+
+del ModuleTestCase
diff --git a/modules/stock_supply_production/tests/test_scenario.py b/modules/stock_supply_production/tests/test_scenario.py
new file mode 100644
index 0000000000..dc1d23e7e5
--- /dev/null
+++ b/modules/stock_supply_production/tests/test_scenario.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import load_doc_tests
+
+
+def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/stock_supply_production/tox.ini b/modules/stock_supply_production/tox.ini
new file mode 100644
index 0000000000..584414c0e1
--- /dev/null
+++ b/modules/stock_supply_production/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/stock_supply_production/* -m unittest discover -s tests
+ coverage report --include=./**/stock_supply_production/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/stock_supply_production/tryton.cfg b/modules/stock_supply_production/tryton.cfg
new file mode 100644
index 0000000000..18220e4f0d
--- /dev/null
+++ b/modules/stock_supply_production/tryton.cfg
@@ -0,0 +1,12 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ product
+ production
+ stock
+ stock_supply
+xml:
+ production.xml
+ stock.xml
+ message.xml
diff --git a/modules/stock_supply_production/view/production_configuration_form.xml b/modules/stock_supply_production/view/production_configuration_form.xml
new file mode 100644
index 0000000000..59b6eed387
--- /dev/null
+++ b/modules/stock_supply_production/view/production_configuration_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/timesheet/.drone.yml b/modules/timesheet/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/timesheet/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/timesheet/.flake8 b/modules/timesheet/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/timesheet/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/timesheet/.isort.cfg b/modules/timesheet/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/timesheet/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/timesheet/CHANGELOG b/modules/timesheet/CHANGELOG
new file mode 100644
index 0000000000..ea520fbc86
--- /dev/null
+++ b/modules/timesheet/CHANGELOG
@@ -0,0 +1,101 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+* Use window domain to show "open" and "closed" timesheet works
+* Remove active from timesheet work
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+* Use ir.calendar.month in report
+* Add date to window name when entering timesheet
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Add UUID on line for synchronisation
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+
+Version 4.2.0 - 2016-11-28
+* Bug fixes (see mercurial logs for details)
+* Add read access to any line for all
+* Add domain on start/end date of work
+* Add user application API
+* Remove tree structure on Work
+* Add optional origin on Work
+
+Version 4.0.0 - 2016-05-02
+* Bug fixes (see mercurial logs for details)
+* Add Python3 support
+
+Version 3.8.0 - 2015-11-02
+* Bug fixes (see mercurial logs for details)
+* Split duration into simple and total duration
+
+Version 3.6.0 - 2015-04-20
+* Bug fixes (see mercurial logs for details)
+* Add support for PyPy
+* Use TimeDelta field
+
+Version 3.4.0 - 2014-10-20
+* Bug fixes (see mercurial logs for details)
+
+Version 3.2.0 - 2014-04-21
+* Bug fixes (see mercurial logs for details)
+
+Version 3.0.0 - 2013-10-21
+* Bug fixes (see mercurial logs for details)
+
+Version 2.8.0 - 2013-04-22
+* Bug fixes (see mercurial logs for details)
+* Add start/end date to work for timesheet
+
+Version 2.6.0 - 2012-10-22
+* Bug fixes (see mercurial logs for details)
+
+Version 2.4.0 - 2012-04-24
+* Bug fixes (see mercurial logs for details)
+* Change record rule for work to use the current company instead of main
+
+Version 2.2.0 - 2011-10-25
+* Bug fixes (see mercurial logs for details)
+
+Version 2.0.0 - 2011-04-27
+* Bug fixes (see mercurial logs for details)
+
+Version 1.8.0 - 2010-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 1.6.0 - 2010-05-12
+* Bug fixes (see mercurial logs for details)
+
+Version 1.4.0 - 2009-10-19
+* Initial release
diff --git a/modules/timesheet/COPYRIGHT b/modules/timesheet/COPYRIGHT
new file mode 100644
index 0000000000..85e100bbec
--- /dev/null
+++ b/modules/timesheet/COPYRIGHT
@@ -0,0 +1,16 @@
+Copyright (C) 2008-2022 Cédric Krier.
+Copyright (C) 2008-2013 Bertrand Chenal.
+Copyright (C) 2008-2022 B2CK SPRL.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/timesheet/LICENSE b/modules/timesheet/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/timesheet/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/timesheet/MANIFEST.in b/modules/timesheet/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/timesheet/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/timesheet/README.rst b/modules/timesheet/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/timesheet/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/timesheet/__init__.py b/modules/timesheet/__init__.py
new file mode 100644
index 0000000000..b763272487
--- /dev/null
+++ b/modules/timesheet/__init__.py
@@ -0,0 +1,24 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.pool import Pool
+
+from . import line, routes, user, work
+
+__all__ = ['register', 'routes']
+
+
+def register():
+ Pool.register(
+ work.Work,
+ work.WorkContext,
+ line.Line,
+ line.EnterLinesStart,
+ line.HoursEmployee,
+ line.HoursEmployeeContext,
+ line.HoursEmployeeWeekly,
+ line.HoursEmployeeMonthly,
+ user.UserApplication,
+ module='timesheet', type_='model')
+ Pool.register(
+ line.EnterLines,
+ module='timesheet', type_='wizard')
diff --git a/modules/timesheet/doc/index.rst b/modules/timesheet/doc/index.rst
new file mode 100644
index 0000000000..eab62177f0
--- /dev/null
+++ b/modules/timesheet/doc/index.rst
@@ -0,0 +1,32 @@
+Timesheet Module
+################
+
+The timesheet module allow to track the time spent by employees on
+various works. This module also comes with several reports that show
+the time spent by employees on works following various time periods.
+
+
+Work
+****
+
+A work is a generic concept that encompass all activities from simple
+tasks to long-running projects. It can be alone or linked to another document.
+The Work model contains the following fields:
+
+- Name or Origin: The name or the origin of the work.
+- Active: A checkbox that allow to disable the work.
+- Company: The company for which the work is (or was) executed.
+
+
+Timesheet Line
+**************
+
+A timesheet line expresses the fact that one employee spends part of
+their time doing specific work on a given date. An optional
+Description field allows extra information to be recorded about what
+has been done.
+
+.. toctree::
+ :maxdepth: 1
+
+ user_application
diff --git a/modules/timesheet/doc/user_application.rst b/modules/timesheet/doc/user_application.rst
new file mode 100644
index 0000000000..9a3dc9f938
--- /dev/null
+++ b/modules/timesheet/doc/user_application.rst
@@ -0,0 +1,30 @@
+Timesheet User Application
+##########################
+
+The timesheet module defines some routes for user applications:
+
+ - `GET` `//timesheet/employees`:
+ return the list of the user employees as dictionary with the keys: `id`
+ and `name`.
+
+ - `GET` `//timesheet/employee//works`:
+ return the list of works available for the employee. The works are
+ dictionary with keys: `id`, `name`, `start` and `end`. The dates are in
+ the format `%Y-%m-%d`.
+
+ - `GET` `//timesheet/employee//lines/`:
+ return the list of timesheet lines for the employee at the date
+ (`%Y-%m-%d'). The lines are dictionary with keys: `id`, `work`,
+ `work.name`, `duration`, `description` and `uuid`. The duration is in
+ seconds.
+
+ - `POST` `//timesheet/line`:
+ Create a line using the data as dictionary of value. The date must be in
+ the format `%Y-%m-%d` and the `duration` in seconds. If a `uuid` value is
+ provided, it will update the record if found instead of create a new one.
+
+ - `PUT` `//timesheet/line/`:
+ Update the line using the data like for the `POST`.
+
+ - `DELETE` `//timesheet/line/`:
+ Delete the line
diff --git a/modules/timesheet/exceptions.py b/modules/timesheet/exceptions.py
new file mode 100644
index 0000000000..ef503d5730
--- /dev/null
+++ b/modules/timesheet/exceptions.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.model.exceptions import ValidationError
+
+
+class CompanyValidationError(ValidationError):
+ pass
+
+
+class DurationValidationError(ValidationError):
+ pass
diff --git a/modules/timesheet/icons/LICENSE b/modules/timesheet/icons/LICENSE
new file mode 100644
index 0000000000..7a4a3ea242
--- /dev/null
+++ b/modules/timesheet/icons/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git a/modules/timesheet/icons/tryton-timesheet.svg b/modules/timesheet/icons/tryton-timesheet.svg
new file mode 100644
index 0000000000..3a12660397
--- /dev/null
+++ b/modules/timesheet/icons/tryton-timesheet.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/modules/timesheet/line.py b/modules/timesheet/line.py
new file mode 100644
index 0000000000..20cf6e574c
--- /dev/null
+++ b/modules/timesheet/line.py
@@ -0,0 +1,366 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import datetime
+
+from sql import Literal
+from sql.aggregate import Max, Sum
+from sql.functions import Extract
+
+from trytond.i18n import gettext
+from trytond.model import Index, ModelSQL, ModelView, Unique, fields
+from trytond.pool import Pool
+from trytond.pyson import Date, Eval, PYSONEncoder, TimeDelta
+from trytond.transaction import Transaction
+from trytond.wizard import Button, StateAction, StateView, Wizard
+
+from .exceptions import DurationValidationError
+
+
+class Line(ModelSQL, ModelView):
+ 'Timesheet Line'
+ __name__ = 'timesheet.line'
+ company = fields.Many2One('company.company', 'Company', required=True,
+ help="The company on which the time is spent.")
+ employee = fields.Many2One(
+ 'company.employee', "Employee", required=True, domain=[
+ ('company', '=', Eval('company', -1)),
+ ['OR',
+ ('start_date', '=', None),
+ ('start_date', '<=', Eval('date', None)),
+ ],
+ ['OR',
+ ('end_date', '=', None),
+ ('end_date', '>=', Eval('date', None)),
+ ],
+ ],
+ help="The employee who spends the time.")
+ date = fields.Date(
+ "Date", required=True,
+ help="When the time is spent.")
+ duration = fields.TimeDelta(
+ 'Duration', 'company_work_time', required=True,
+ domain=[
+ ('duration', '>=', TimeDelta()),
+ ])
+ work = fields.Many2One(
+ 'timesheet.work', "Work", required=True,
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ['OR',
+ ('timesheet_start_date', '=', None),
+ ('timesheet_start_date', '<=', Eval('date', None)),
+ ],
+ ['OR',
+ ('timesheet_end_date', '=', None),
+ ('timesheet_end_date', '>=', Eval('date', None)),
+ ],
+ ],
+ help="The work on which the time is spent.")
+ description = fields.Char('Description',
+ help="Additional description of the work done.")
+ uuid = fields.Char("UUID", readonly=True, strip=False)
+
+ @classmethod
+ def __setup__(cls):
+ super(Line, cls).__setup__()
+ cls._order = [
+ ('date', 'DESC'),
+ ('id', 'DESC'),
+ ]
+ t = cls.__table__()
+ cls._sql_constraints = [
+ ('uuid_unique', Unique(t, t.uuid),
+ 'timesheet.msg_line_uuid_unique'),
+ ]
+ cls._sql_indexes.update({
+ Index(
+ t,
+ (t.date, Index.Equality()),
+ (t.company, Index.Equality()),
+ (t.employee, Index.Equality())),
+ Index(
+ t,
+ (t.date, Index.Range()),
+ (t.employee, Index.Equality())),
+ Index(
+ t,
+ (Extract('YEAR', t.date), Index.Equality()),
+ (Extract('WEEK', t.date), Index.Equality()),
+ (t.employee, Index.Equality())),
+ Index(
+ t,
+ (Extract('YEAR', t.date), Index.Equality()),
+ (Extract('MONTH', t.date), Index.Equality()),
+ (t.employee, Index.Equality())),
+ })
+
+ @classmethod
+ def __register__(cls, module_name):
+ transaction = Transaction()
+ cursor = transaction.connection.cursor()
+ update = transaction.connection.cursor()
+ table = cls.__table_handler__(module_name)
+ sql_table = cls.__table__()
+ pool = Pool()
+ Work = pool.get('timesheet.work')
+ work = Work.__table__()
+
+ created_company = not table.column_exist('company')
+
+ super(Line, cls).__register__(module_name)
+
+ # Migration from 3.4: new company field
+ if created_company:
+ # Don't use FROM because SQLite nor MySQL support it.
+ update.execute(*sql_table.update(
+ [sql_table.company], [work.select(work.company,
+ where=work.id == sql_table.work)]))
+ # Migration from 3.4: change hours into timedelta duration
+ if table.column_exist('hours'):
+ table.drop_constraint('check_move_hours_pos')
+ cursor.execute(*sql_table.select(
+ sql_table.id, sql_table.hours))
+ for id_, hours in cursor:
+ duration = datetime.timedelta(hours=hours)
+ update.execute(*sql_table.update(
+ [sql_table.duration],
+ [duration],
+ where=sql_table.id == id_))
+ table.drop_column('hours')
+
+ @staticmethod
+ def default_company():
+ return Transaction().context.get('company')
+
+ @staticmethod
+ def default_employee():
+ User = Pool().get('res.user')
+ employee_id = None
+ if Transaction().context.get('employee'):
+ employee_id = Transaction().context['employee']
+ else:
+ user = User(Transaction().user)
+ if user.employee:
+ employee_id = user.employee.id
+ if employee_id:
+ return employee_id
+
+ @staticmethod
+ def default_date():
+ Date_ = Pool().get('ir.date')
+ return Transaction().context.get('date') or Date_.today()
+
+ @classmethod
+ def validate_fields(cls, lines, field_names):
+ super().validate_fields(lines, field_names)
+ cls.check_duration(lines, field_names)
+
+ @classmethod
+ def check_duration(cls, lines, field_names=None):
+ if field_names and 'duration' not in field_names:
+ return
+ for line in lines:
+ if line.duration < datetime.timedelta():
+ raise DurationValidationError(
+ gettext('timesheet.msg_line_duration_positive',
+ line=line.rec_name))
+
+ @classmethod
+ def copy(cls, lines, default=None):
+ if default is not None:
+ default = default.copy()
+ else:
+ default = {}
+ default.setdefault('uuid')
+ return super().copy(lines, default=default)
+
+ @property
+ def hours(self):
+ return self.duration.total_seconds() / 60 / 60
+
+ def to_json(self):
+ return {
+ 'id': self.id,
+ 'work': self.work.id,
+ 'work.name': self.work.rec_name,
+ 'duration': self.duration.total_seconds(),
+ 'description': self.description,
+ 'uuid': self.uuid,
+ }
+
+
+class EnterLinesStart(ModelView):
+ 'Enter Lines'
+ __name__ = 'timesheet.line.enter.start'
+ employee = fields.Many2One('company.employee', 'Employee', required=True,
+ domain=[
+ ('company', '=', Eval('context', {}).get('company', -1)),
+ ['OR',
+ ('start_date', '=', None),
+ ('start_date', '<=', Eval('date', None)),
+ ],
+ ['OR',
+ ('end_date', '=', None),
+ ('end_date', '>=', Eval('date', None)),
+ ],
+ ],
+ help="The employee who spends the time.")
+ date = fields.Date('Date', required=True,
+ help="When the time is spent.")
+
+ @staticmethod
+ def default_employee():
+ Line = Pool().get('timesheet.line')
+ return Line.default_employee()
+
+ @staticmethod
+ def default_date():
+ Line = Pool().get('timesheet.line')
+ return Line.default_date()
+
+
+class EnterLines(Wizard):
+ 'Enter Lines'
+ __name__ = 'timesheet.line.enter'
+ start = StateView('timesheet.line.enter.start',
+ 'timesheet.line_enter_start_view_form', [
+ Button('Cancel', 'end', 'tryton-cancel'),
+ Button('Enter', 'enter', 'tryton-ok', default=True),
+ ])
+ enter = StateAction('timesheet.act_line_form')
+
+ def do_enter(self, action):
+ pool = Pool()
+ Lang = pool.get('ir.lang')
+ date = self.start.date
+ date = Date(date.year, date.month, date.day)
+ action['pyson_domain'] = PYSONEncoder().encode([
+ ('employee', '=', self.start.employee.id),
+ ('company', '=', self.start.employee.company.id),
+ ('date', '=', date),
+ ])
+ action['pyson_context'] = PYSONEncoder().encode({
+ 'employee': self.start.employee.id,
+ 'company': self.start.employee.company.id,
+ 'date': date,
+ })
+ action['name'] += ' @ %(date)s - %(employee)s' % {
+ 'date': Lang.get().strftime(self.start.date),
+ 'employee': self.start.employee.rec_name,
+ }
+ return action, {}
+
+ def transition_enter(self):
+ return 'end'
+
+
+class HoursEmployee(ModelSQL, ModelView):
+ 'Hours per Employee'
+ __name__ = 'timesheet.hours_employee'
+ employee = fields.Many2One('company.employee', 'Employee')
+ duration = fields.TimeDelta('Duration', 'company_work_time')
+
+ @staticmethod
+ def table_query():
+ pool = Pool()
+ Line = pool.get('timesheet.line')
+ line = Line.__table__()
+ where = Literal(True)
+ if Transaction().context.get('start_date'):
+ where &= line.date >= Transaction().context['start_date']
+ if Transaction().context.get('end_date'):
+ where &= line.date <= Transaction().context['end_date']
+ return line.select(
+ line.employee.as_('id'),
+ Max(line.create_uid).as_('create_uid'),
+ Max(line.create_date).as_('create_date'),
+ Max(line.write_uid).as_('write_uid'),
+ Max(line.write_date).as_('write_date'),
+ line.employee,
+ Sum(line.duration).as_('duration'),
+ where=where,
+ group_by=line.employee)
+
+
+class HoursEmployeeContext(ModelView):
+ 'Hours per Employee Context'
+ __name__ = 'timesheet.hours_employee.context'
+ start_date = fields.Date('Start Date')
+ end_date = fields.Date('End Date')
+
+
+class HoursEmployeeWeekly(ModelSQL, ModelView):
+ 'Hours per Employee per Week'
+ __name__ = 'timesheet.hours_employee_weekly'
+ year = fields.Integer("Year")
+ week = fields.Integer("Week")
+ employee = fields.Many2One('company.employee', 'Employee')
+ duration = fields.TimeDelta('Duration', 'company_work_time')
+
+ @classmethod
+ def __setup__(cls):
+ super(HoursEmployeeWeekly, cls).__setup__()
+ cls._order.insert(0, ('year', 'DESC'))
+ cls._order.insert(1, ('week', 'DESC'))
+ cls._order.insert(2, ('employee', 'ASC'))
+
+ @classmethod
+ def table_query(cls):
+ pool = Pool()
+ Line = pool.get('timesheet.line')
+ line = Line.__table__()
+ year_column = Extract('YEAR', line.date).as_('year')
+ week_column = Extract('WEEK', line.date).as_('week')
+ return line.select(
+ Max(Extract('WEEK', line.date)
+ + Extract('YEAR', line.date) * 100
+ + line.employee * 1000000).as_('id'),
+ Max(line.create_uid).as_('create_uid'),
+ Max(line.create_date).as_('create_date'),
+ Max(line.write_uid).as_('write_uid'),
+ Max(line.write_date).as_('write_date'),
+ year_column,
+ week_column,
+ line.employee,
+ Sum(line.duration).as_('duration'),
+ group_by=(year_column, week_column, line.employee))
+
+
+class HoursEmployeeMonthly(ModelSQL, ModelView):
+ 'Hours per Employee per Month'
+ __name__ = 'timesheet.hours_employee_monthly'
+ year = fields.Integer("Year")
+ month = fields.Many2One('ir.calendar.month', "Month")
+ employee = fields.Many2One('company.employee', 'Employee')
+ duration = fields.TimeDelta('Duration', 'company_work_time')
+
+ @classmethod
+ def __setup__(cls):
+ super(HoursEmployeeMonthly, cls).__setup__()
+ cls._order.insert(0, ('year', 'DESC'))
+ cls._order.insert(1, ('month.index', 'DESC'))
+ cls._order.insert(2, ('employee', 'ASC'))
+
+ @classmethod
+ def table_query(cls):
+ pool = Pool()
+ Line = pool.get('timesheet.line')
+ Month = pool.get('ir.calendar.month')
+ line = Line.__table__()
+ month = Month.__table__()
+ year_column = Extract('YEAR', line.date).as_('year')
+ month_index = Extract('MONTH', line.date)
+ return line.join(month, condition=month_index == month.id).select(
+ Max(Extract('MONTH', line.date)
+ + Extract('YEAR', line.date) * 100
+ + line.employee * 1000000).as_('id'),
+ Max(line.create_uid).as_('create_uid'),
+ Max(line.create_date).as_('create_date'),
+ Max(line.write_uid).as_('write_uid'),
+ Max(line.write_date).as_('write_date'),
+ year_column,
+ month.id.as_('month'),
+ line.employee,
+ Sum(line.duration).as_('duration'),
+ group_by=(year_column, month.id, line.employee))
diff --git a/modules/timesheet/line.xml b/modules/timesheet/line.xml
new file mode 100644
index 0000000000..b5e24a6c9f
--- /dev/null
+++ b/modules/timesheet/line.xml
@@ -0,0 +1,222 @@
+
+
+
+
+
+ timesheet.line
+ form
+ line_form
+
+
+ timesheet.line
+ tree
+ line_tree
+
+
+ Lines
+ timesheet.line
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Timesheet Lines
+ timesheet.line
+
+
+
+
+
+
+
+
+
+
+
+
+
+ form_relate
+ timesheet.work,-1
+
+
+
+
+ User in companies
+
+
+
+
+
+
+
+
+
+ Own timesheet line
+
+
+
+
+
+
+
+
+
+
+ Any timesheet line
+
+
+
+
+
+
+
+
+
+
+ timesheet.line.enter.start
+ form
+ line_enter_start_form
+
+
+
+ Enter Timesheet
+ timesheet.line.enter
+
+
+
+
+ timesheet.hours_employee
+ tree
+ hours_employee_tree
+
+
+ timesheet.hours_employee
+ graph
+ hours_employee_graph
+
+
+ Hours per Employee
+ timesheet.hours_employee
+ timesheet.hours_employee.context
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Own employee hours
+
+
+
+
+
+
+
+
+
+
+ Any employee hours
+
+
+
+
+
+
+
+
+
+
+ timesheet.hours_employee.context
+ form
+ hours_employee_context_form
+
+
+
+ timesheet.hours_employee_weekly
+ tree
+ hours_employee_weekly_tree
+
+
+ Hours per Employee per Week
+ timesheet.hours_employee_weekly
+
+
+
+
+
+
+
+
+
+ timesheet.hours_employee_monthly
+ tree
+ hours_employee_monthly_tree
+
+
+ Hours per Employee per Month
+ timesheet.hours_employee_monthly
+
+
+
+
+
+
+
+
+
diff --git a/modules/timesheet/locale/bg.po b/modules/timesheet/locale/bg.po
new file mode 100644
index 0000000000..5471320ca5
--- /dev/null
+++ b/modules/timesheet/locale/bg.po
@@ -0,0 +1,400 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Продължителност"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "Служител"
+
+#, fuzzy
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "Крайна дата"
+
+#, fuzzy
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "Начална дата"
+
+#, fuzzy
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "Продължителност"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "Служител"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "Месец"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "Година"
+
+#, fuzzy
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Продължителност"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "Служител"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "Седмица"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "Година"
+
+#, fuzzy
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Фирма"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Дата"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Описание"
+
+#, fuzzy
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Продължителност"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "Служител"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr ""
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Задача"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Дата"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Служител"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Фирма"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr ""
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Име"
+
+#, fuzzy
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "Източник"
+
+#, fuzzy
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Ред от график"
+
+#, fuzzy
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Редове от график"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Задача"
+
+#, fuzzy
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "От дата"
+
+#, fuzzy
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "До дата"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr ""
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr ""
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr ""
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Редове от график"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Зачади"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Configuration"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Часове на служител"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Reporting"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Зачади"
+
+#, fuzzy
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Timesheet Administration"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Часове на служител"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr ""
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Часове за служител за месец"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Часове на служител за седмица"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Ред от график"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr ""
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Задача"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Управление на графици"
+
+#, fuzzy
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "Продължителност"
+
+#, fuzzy
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "Продължителност"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "Отказ"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "Въвеждане"
diff --git a/modules/timesheet/locale/ca.po b/modules/timesheet/locale/ca.po
new file mode 100644
index 0000000000..f1bd078bba
--- /dev/null
+++ b/modules/timesheet/locale/ca.po
@@ -0,0 +1,369 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Temps"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "Empleat"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "Data final"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "Data inicial"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "Temps"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "Empleat"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "Mes"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "Any"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Temps"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "Empleat"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "Setmana"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "Any"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Descripció"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Temps"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "Empleat"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr "Identificador únic universal"
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Treball"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Empleat"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr "Temps del full de treball"
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Nom"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "Origen"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Final del full de treball"
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Línies del full de treball"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr "Inici del full de treball"
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Treball"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "Des de la data"
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "Fins a la data"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr "L'empresa on s'ha invertit el temps."
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr "Quan s'ha realitzat el treball."
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr "Descripció addicional del treball realitzat."
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr "El empleat que realitzat el treball."
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr "El treball en que s'ha invertit el temps."
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr "Quan s'han realitzat els treballs."
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr "L'empleat que ha realitzat els treballs."
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr "Feu que el treball pertanyi a l'empresa."
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr "Temps total dedicat en aquest treball."
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr "El identificador principal del treball."
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr "Utilitzeu-ho per relacionar el temps invertit amb altres registres."
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr "Restringeix afegir línies desprès de la data."
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr "Inverteix temps en aquest treball."
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr "Restringeix afegir línies abans de la data."
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr "No tinguis en compte les línies abans de la data."
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr "No tinguis en compte les línies desprès de la data."
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Hores per empleat"
+
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Hores per empleat i mes"
+
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Hores per empleat i setmana"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Afegeix full de treball"
+
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "Línies"
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Línies del full de treball"
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Treballs"
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Treballs"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr "Tot"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr "Obert"
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr "La duració de la línia \"%(line)s\" ha de ser positiva."
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr "El UUID de la línia del full de treball ha de ser únic."
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+"Les empreses associades amb el treball \"%(work)s\" i les del seu origen "
+"difereixen."
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr "L'origen ha de ser únic per empresa."
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr "Qualsevol hora d'empleat"
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr "Hores del propi empleat"
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr "Línies del full de treball pròpies"
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr "Qualsevol línia del full de treball"
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr "Usuari a les empreses"
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr "Usuari a les empreses"
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Configuració"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Hores per empleat"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Hores per empleat i mes"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Hores per empleat i setmana"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Afegeix full de treball"
+
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "Línies"
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Informes"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Full de treball"
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Treballs"
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Treballs"
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Administració de fulls de treball"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Hores per empleat"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr "Context hores per empleat"
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Hores per empleat i mes"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Hores per empleat i setmana"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Línia de full de treball"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "Afegir línies"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Treball"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr "Context treball"
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Full de treball"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "Temps"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "Temps"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "Cancel·la"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "Afegeix"
diff --git a/modules/timesheet/locale/cs.po b/modules/timesheet/locale/cs.po
new file mode 100644
index 0000000000..9b5a705abd
--- /dev/null
+++ b/modules/timesheet/locale/cs.po
@@ -0,0 +1,378 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr ""
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr ""
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Works"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Namu"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Timesheet Lines"
+
+#, fuzzy
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Timesheet Lines"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Works"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr ""
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr ""
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr ""
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Timesheet Lines"
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Configuration"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Reporting"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Timesheet Administration"
+
+#, fuzzy
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Timesheet Lines"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Works"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr ""
diff --git a/modules/timesheet/locale/de.po b/modules/timesheet/locale/de.po
new file mode 100644
index 0000000000..a2a76f3d6e
--- /dev/null
+++ b/modules/timesheet/locale/de.po
@@ -0,0 +1,370 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Dauer"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "Mitarbeiter"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "Enddatum"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "Startdatum"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "Dauer"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "Mitarbeiter"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "Monat"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "Jahr"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Dauer"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "Mitarbeiter"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "Woche"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "Jahr"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Unternehmen"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Datum"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Beschreibung"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Dauer"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "Mitarbeiter"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr "UUID"
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Tätigkeit"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Datum"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Mitarbeiter"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Unternehmen"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr "Zeiterfassung Dauer"
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Name"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "Herkunft"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Zeiterfassung Ende"
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Zeiterfassungspositionen"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr "Zeiterfassung Beginn"
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Tätigkeit"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "Von Datum"
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "Bis Datum"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr "Das Unternehmen für das Zeit aufgewendet wird."
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr "Wann die Zeit aufgewendet wird."
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr "Zusätzliche Beschreibung der erledigten Aufgabe."
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr "Der Mitarbeiter der Zeit aufwendet."
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr "Die Aufgabe für die Zeit aufgewendet wird."
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr "Wann die Zeit aufgewendet wird."
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr "Der Mitarbeiter der Zeit aufwendet."
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr "Die Aufgabe dem Unternehmen zuordnen."
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr "Die gesamte Zeit, die für diese Aufgabe verwendet wurde."
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr "Das Hauptidentifizierungsmerkmal der Aufgabe."
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr "Die aufgewendete Zeit auf andere Datensätze anwenden."
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr "Hinzufügen von Positionen nach dem Datum beschränken."
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr "Zeit für diese Aufgabe aufwenden."
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr "Hinzufügen von Positionen vor dem Datum beschränken."
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr "Buchungspositionen vor dem Datum nicht berücksichtigen."
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr "Buchungspositionen nach dem Datum nicht berücksichtigen."
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Stunden pro Mitarbeiter"
+
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Stunden pro Mitarbeiter und Monat"
+
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Stunden pro Mitarbeiter und Woche"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Zur Zeiterfassung"
+
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "Zeiterfassungspositionen"
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Zeiterfassungspositionen"
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Tätigkeiten"
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Tätigkeiten"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr "Alle"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr "Offen"
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr "Die Zeitdauer von Zeile \"%(line)s\" muss positiv sein."
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr "Die UUID der Zeiterfassungsposition muss eindeutig sein."
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+"Die mit der Tätigkeit \"%(work)s\" und Ihrer Herkunft verknüpften "
+"Unternehmen weichen voneinander ab."
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr ""
+"Die Herkunft der Arbeit pro Unternehmen kann nur einmal vergeben werden."
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr "Alle Mitarbeiterzeiten"
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr "Zeiterfassungspositionen Auswertung (Nur Eigene)"
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr "Eigene Zeiterfassungspositionen"
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr "Alle Zeiterfassungspositionen"
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr "Benutzer im Unternehmen"
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr "Benutzer im Unternehmen"
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Einstellungen"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Stunden pro Mitarbeiter"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Stunden pro Mitarbeiter und Monat"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Stunden pro Mitarbeiter und Woche"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Zur Zeiterfassung"
+
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "Zeiterfassungspositionen"
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Auswertungen"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Zeiterfassung"
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Tätigkeiten"
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Tätigkeiten"
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Zeiterfassung Administration"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Stunden pro Mitarbeiter"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr "Stunden pro Mitarbeiter Kontext"
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Stunden pro Mitarbeiter und Monat"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Stunden pro Mitarbeiter und Woche"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Zeiterfassungsposition"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "Eingabe Zeilen"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Tätigkeit"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr "Tätigkeit Kontext"
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Zeiterfassung"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "Dauer"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "Dauer"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "Abbrechen"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "Zur Eingabe"
diff --git a/modules/timesheet/locale/es.po b/modules/timesheet/locale/es.po
new file mode 100644
index 0000000000..3cf1e6c504
--- /dev/null
+++ b/modules/timesheet/locale/es.po
@@ -0,0 +1,368 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Tiempo"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "Empleado"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "Fecha final"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "Fecha inicial"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "Tiempo"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "Empleado"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "Mes"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "Año"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Tiempo"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "Empleado"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "Semana"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "Año"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Fecha"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Descripción"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Tiempo"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "Empleado"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr "Identificador único universal"
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Trabajo"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Fecha"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Empleado"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr "Duración del parte de trabajo"
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Nombre"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "Origen"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Fin de parte de trabajo"
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Líneas de parte de trabajo"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr "Inicio de parte de trabajo"
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Trabajo"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "Desde la fecha"
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "Hasta la fecha"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr "La empresa en la que se ha invertido el tiempo."
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr "Cuando se ha realizado el trabajo."
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr "Descripción adicional del trabajo realizado."
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr "El empleado que ha realizado el trabajo."
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr "El trabajo en que se ha invertido el tiempo."
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr "Cuando se han realizado los trabajos."
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr "El empleado que ha realizado los trabajos."
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr "Hace que el trabajo pertenezca a la empresa."
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr "Tiempo total dedicado en este trabajo."
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr "El identificador principal del trabajo."
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr "Utilizado para relacionar el tiempo invertido con otros registros."
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr "No permite añadir líneas después de esta fecha."
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr "Invierte tiempo en este trabajo."
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr "No permite añadir líneas antes de esta fecha."
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr "No tiene en cuenta las lineas antes de la fecha."
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr "No tiene en cuenta las lineas después de la fecha."
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Horas por empleado"
+
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Horas por empleado y mes"
+
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Horas por empleado y semana"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Añadir parte de trabajo"
+
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "Líneas"
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Líneas del parte de trabajo"
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Trabajos"
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Trabajos"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr "Todo"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr "Abierto"
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr "La duración de la línea \"%(line)s\" debe ser positiva."
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr "El UUID de la linea del parte de trabajo tiene que ser único."
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+"Las empresas asociadas con el trabajo \"%(work)s\" y sus orígenes difieren."
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr "El origen debe ser único por empresa."
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr "Cualquier hora de empleado"
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr "Horas del propio empleado"
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr "Lineas del parte de trabajo propias"
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr "Cualquier línea del parte de trabajo"
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr "Usuario en las empresas"
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr "Usuario en las empresas"
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Configuración"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Horas por empleado"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Horas por empleado y mes"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Horas por empleado y semana"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Añadir parte de trabajo"
+
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "Líneas"
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Informes"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Partes de trabajo"
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Trabajos"
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Trabajos"
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Administración de partes de trabajo"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Horas por empleado"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr "Contexto de Horas por empleado"
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Horas por empleado y mes"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Horas por empleado y semana"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Línea de parte de trabajo"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "Añadir líneas"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Trabajo"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr "Contexto trabajo"
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Parte de trabajo"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "Tiempo"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "Tiempo"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "Añadir"
diff --git a/modules/timesheet/locale/es_419.po b/modules/timesheet/locale/es_419.po
new file mode 100644
index 0000000000..70940fc1e5
--- /dev/null
+++ b/modules/timesheet/locale/es_419.po
@@ -0,0 +1,374 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Duración"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "Duración"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Duración"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr ""
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr ""
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Duración"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr ""
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr ""
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr ""
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr ""
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr ""
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr ""
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr ""
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr ""
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr ""
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr ""
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Horas por empleado por mes"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Horas por empleado por semana"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "Ingresar líneas"
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr "La duración de la línea \"%(line)s\" debe ser positiva."
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Horas por empleado por mes"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Horas por empleado por semana"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "Ingresar líneas"
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr ""
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr ""
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr ""
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr "Contexto de horas por empleado"
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Horas por empleado por mes"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Horas por empleado por semana"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr ""
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "Ingresar líneas"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr ""
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr "Contexto de trabajo"
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr ""
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "Duración"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "Duración"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "Ingresar"
diff --git a/modules/timesheet/locale/et.po b/modules/timesheet/locale/et.po
new file mode 100644
index 0000000000..c8dfde3b2b
--- /dev/null
+++ b/modules/timesheet/locale/et.po
@@ -0,0 +1,372 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Kestvus"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "Töötaja"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "Lõppkuupäev"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "Alguskuupäev"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "Kestvus"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "Töötaja"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "Kuu"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "Aasta"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Kestvus"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "Töötaja"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "Nädal"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "Aasta"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Ettevõte"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Kuupäev"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Kirjeldus"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Kestvus"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "Töötaja"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr "UUID"
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Töö"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Kuupäev"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Töötaja"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Ettevõte"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr "Töögraafiku kestvus"
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Nimi"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "Päritolu"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Töögraafiku lõpp"
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Töögraafiku read"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr "Töögraafiku algus"
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Töö"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "Kuupäevast"
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "Kuupäevani"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr "Millal aega kulutati"
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr ""
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr "Millal aega kulutati"
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr ""
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr ""
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr "Sellele tööle kulunud aeg"
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Tunde töötaja kohta"
+
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Tunde töötaja kohta kuus"
+
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Tunde töötaja kohta nädalas"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Sisesta töögraafik"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "Lisa read"
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Töögraafiku read"
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Tööd"
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Tööd"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr "Kõigi töötajate tunnid"
+
+#, fuzzy
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr "Oma töötaja tunnid"
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr "Oma tööajatabeli rida"
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr "Kõik tööaja tabeli read"
+
+#, fuzzy
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr "Kasutaja ettevõttes"
+
+#, fuzzy
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr "Kasutaja ettevõttes"
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Seadistus"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Tunde töötaja kohta"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Tunde töötaja kohta kuus"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Tunde töötaja kohta nädalas"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Sisesta töögraafik"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "Lisa read"
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Aruandlus"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Töögraafik"
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Tööd"
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Tööd"
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Töögraafiku administreerimine"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Tunde töötaja kohta"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr "Tunde töötaja kohta sisu"
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Tunde töötaja kohta kuus"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Tunde töötaja kohta nädalas"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Töögraafiku rida"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "Lisa read"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Töö"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr "Töö sisu"
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Töögraafik"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "Kestvus"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "Kestvus"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "Tühista"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "Sisesta"
diff --git a/modules/timesheet/locale/fa.po b/modules/timesheet/locale/fa.po
new file mode 100644
index 0000000000..c9fb48ce62
--- /dev/null
+++ b/modules/timesheet/locale/fa.po
@@ -0,0 +1,369 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "مدت زمان"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "کارمند"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "تاریخ پایان"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "تاریخ شروع"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "مدت زمان"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "کارمند"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "ماه"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "سال"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "مدت زمان"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "کارمند"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "هفته"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "سال"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "شرکت"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "تاریخ"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "شرح"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "مدت زمان"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "کارمند"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr "شناسه کاربری"
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "کار"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "تاریخ"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "کارمند"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "شرکت"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr "طول مدت جدول زمانی"
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "نام"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "مبداء"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "پایان جدول زمانی"
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "سطرهای جدول زمانی"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr "شروع جدول زمانی"
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "کار"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "از تاریخ"
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "تا تاریخ"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr "شرکتی که مدت زمان در آن صرف شده است."
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr "هنگامی که زمان صرف شد."
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr "توضیحات اضافی کارانجام شده."
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr "کارمندی که زمان را صرف می کند."
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr "کاری که زمان صرف آن شده است."
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr "هنگامی که زمان صرف شد."
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr "کارمندی که زمان را صرف می کند."
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr "کار متعلق به شرکت را بسازید."
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr "کل زمان صرف شده در این کار."
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr "شناسه اصلی کار."
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr "استفاده از مرتبط کردن زمان صرف شده برای پرونده های دیگر."
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr "محدودیت افزودن سطرهای بعد از تاریخ."
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr "زمان صرف شده روی این کار."
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr "محدودیت افزودن سطرهای قبل از تاریخ."
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr "سطرهای قبل از تاریخ را حساب نکنید."
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr "سطرهای بعد از تاریخ را حساب نکنید."
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "ساعات در هر کارمند"
+
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "ساعات در هر کارمند در هر ماه"
+
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "ساعات در هر کارمند در هر هفته"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "جدول زمانی را وارد کنید"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "واردکردن سطرها"
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "سطرهای جدول زمانی"
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "کارها"
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "کارها"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr "طول مدت سطر : \"%s\" باید مثبت باشد."
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr "شناسه کاربر در جدول زمانی باید منحصربفرد باشد."
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr "شرکت های مرتبط با کار:\"%(work)s\" و منشاء آنها متفاوت است."
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr "منشا باید در هر شرکتی منحصر به فرد باشد."
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "پیکربندی"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "ساعات در هر کارمند"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "ساعات در هر کارمند در هر ماه"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "ساعات در هر کارمند در هر هفته"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "جدول زمانی را وارد کنید"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "واردکردن سطرها"
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "گزارش گیری"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "جدول زمانی"
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "کارها"
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "کارها"
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "مدیریت جدول زمانی"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "ساعات در هر کارمند"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr "مفاد ساعات در هر کارمند"
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "ساعات در هر کارمند در هر ماه"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "ساعات در هر کارمند در هر هفته"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "سطر جدول زمانی"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "واردکردن سطرها"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "کار"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr "مفاد کار"
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "جدول زمانی"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "مدت زمان"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "مدت زمان"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "انصراف"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "وارد کردن"
diff --git a/modules/timesheet/locale/fi.po b/modules/timesheet/locale/fi.po
new file mode 100644
index 0000000000..96f2e78459
--- /dev/null
+++ b/modules/timesheet/locale/fi.po
@@ -0,0 +1,377 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr ""
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr ""
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Works"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr ""
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Timesheet Lines"
+
+#, fuzzy
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Timesheet Lines"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Works"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr ""
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr ""
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr ""
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Timesheet Lines"
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Configuration"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Reporting"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Timesheet Administration"
+
+#, fuzzy
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Timesheet Lines"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Works"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr ""
diff --git a/modules/timesheet/locale/fr.po b/modules/timesheet/locale/fr.po
new file mode 100644
index 0000000000..321584eb81
--- /dev/null
+++ b/modules/timesheet/locale/fr.po
@@ -0,0 +1,368 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Durée"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "Employé"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "Date de fin"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "Date de début"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "Durée"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "Employé"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "Mois"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "Année"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Durée"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "Employé"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "Semaine"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "Année"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Société"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Date"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Description"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Durée"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "Employé"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr "UUID"
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Travail"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Date"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Employé"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Société"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr "Durée de feuille de présence"
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Nom"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "Origine"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Fin de feuille de présence"
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Lignes de feuille de présence"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr "Début de feuille de présence"
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Travail"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "Date de début"
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "Date de fin"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr "La société pour laquelle le temps est passé."
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr "Quand le temps a été passé."
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr "Description additionnelle du travail réalisé."
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr "L'employé qui a passé le temps."
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr "Le travail sur lequel le temps est passé."
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr "Quand le temps a été passé."
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr "L'employé qui a passé le temps."
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr "Faire appartenir le travail à la société."
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr "Temps total passé sur ce travail."
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr "L'identifiant principal du travail."
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr "Sert à lier le temps passé sur d'autres enregistrements."
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr "Restreint l'ajout de lignes après la date."
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr "Passer du temps sur ce travail."
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr "Restreint l'ajout de lignes avant la date."
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr "Ne pas prendre en compte les lignes avant la date."
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr "Ne pas prendre en compte les lignes après la date."
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Heures par employé"
+
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Heures par employé par mois"
+
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Heures par employé par semaine"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Entrer une feuille de présence"
+
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "Lignes"
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Lignes de feuille de présence"
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Travaux"
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Travaux"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr "Tous"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr "Ouverts"
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr "La durée de la ligne « %(line)s » doit être positive."
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr "L'UUID des lignes de feuille de présence doit être unique."
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+"Les sociétés associées au travail « %(work)s » et son origine diffèrent."
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr "L'origine doit être unique par société."
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr "N'importe quelles heures d'employés"
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr "Heures d'employé propre"
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr "Ligne de feuille de présence propre"
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr "N'importe quelle ligne de feuille de présence"
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr "Utilisateur dans les sociétés"
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr "Utilisateur dans les sociétés"
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Configuration"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Heures par employé"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Heures par employé par mois"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Heures par employé par semaine"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Entrer un feuille de présence"
+
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "Lignes"
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Rapports"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Feuilles de présence"
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Travaux"
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Travaux"
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Administration des feuilles de présence"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Heures par employé"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr "Heures par employé contexte"
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Nombre d'heures par employé par mois"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Nombre d'heures par employé par semaine"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Ligne de feuille de présence"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "Entrer les lignes"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Travail"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr "Travail contexte"
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Feuilles de présence"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "Durée"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "Durée"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "Annuler"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "Entrer"
diff --git a/modules/timesheet/locale/hu.po b/modules/timesheet/locale/hu.po
new file mode 100644
index 0000000000..6ed5efbe4a
--- /dev/null
+++ b/modules/timesheet/locale/hu.po
@@ -0,0 +1,392 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Időtartam"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "Alkalmazott"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "Időtartam"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "Alkalmazott"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "Hónap"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "Év"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Időtartam"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "Alkalmazott"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "Hét"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "Év"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Társaság"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Dátum"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Leírás"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Időtartam"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "Alkalmazott"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr ""
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Tevékenység"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Dátum"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Alkalmazott"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Társaság"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr "Időtartam"
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Név"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr ""
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Időkövetés vége"
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Időpozíció"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr "Időkövetés kezdete"
+
+#, fuzzy
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Tevékenység"
+
+#, fuzzy
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "Dátumtól"
+
+#, fuzzy
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "Dátumig"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr ""
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr ""
+
+#, fuzzy
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr "Az össz idő, ami erre a feladatra lett fordítva"
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr ""
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "Sor hozzáadás"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Timesheet Lines"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Tevékenység"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr "A \"%(line)s\" sor időtartama pozitívnak kell lenni."
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Configuration"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Óra per alkalmazott"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "Sor hozzáadás"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Reporting"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Tevékenység"
+
+#, fuzzy
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Timesheet Administration"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Óra per alkalmazott"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr ""
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Óra per alkalmazott per hónap"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Óra per alkalmazott per hét"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Időpozíció"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "Sor hozzáadás"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Tevékenység"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Időtartam"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "Időtartam"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "Időtartam"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "Mégse"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "Bevitel"
diff --git a/modules/timesheet/locale/id.po b/modules/timesheet/locale/id.po
new file mode 100644
index 0000000000..2e107534f7
--- /dev/null
+++ b/modules/timesheet/locale/id.po
@@ -0,0 +1,369 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Durasi"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "Karyawan"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "Tanggal Akhir"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "Tanggal Awal"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "Karyawan"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "Bulan"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "Tahun"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Durasi"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "Karyawan"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "Pekan"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "Tahun"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Perusahaan"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Tanggal"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Deskripsi"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Durasi"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "Karyawan"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr "UUID"
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Kerja"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Tanggal"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Karyawan"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Perusahaan"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr ""
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Nama"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "Asal"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr ""
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr ""
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr ""
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Kerja"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "Dari Tanggal"
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "Ke Tanggal"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr ""
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr ""
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr ""
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr "Pengguna di dalam perusahaan"
+
+#, fuzzy
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr "Pengguna di dalam perusahaan"
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Konfigurasi"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Pelaporan"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr ""
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr ""
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr ""
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr ""
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr ""
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr ""
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr ""
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr ""
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr ""
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr ""
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr ""
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "Batal"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr ""
diff --git a/modules/timesheet/locale/it.po b/modules/timesheet/locale/it.po
new file mode 100644
index 0000000000..84724689ff
--- /dev/null
+++ b/modules/timesheet/locale/it.po
@@ -0,0 +1,387 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Durata"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "Dipendente"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "Data finale"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "Data iniziale"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "Durata"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "Dipendente"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "Mese"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "Anno"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Durata"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "Dipendente"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "Settimana"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "Anno"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Azienda"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Descrizione"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Durata"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "Dipendente"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr ""
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Lavoro"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Dipendente"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Azienda"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr "Durata timesheet"
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Nome"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "Origine"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Fine timesheet"
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Righe timesheet"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr "inizio timesheet"
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Lavoro"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "Data Iniziale"
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "a data"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr ""
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr ""
+
+#, fuzzy
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr "Tempo totale speso nel lavoro"
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr ""
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "Inserire righe"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Timesheet Lines"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr "La durata della riga \"%(line)s\" dev'essere positiva."
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr "L'origine dev'essere unica per azienda."
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Configurazione"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "Inserire righe"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Reporting"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Timesheet Administration"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Ore per dipendente"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr "Context ore per dipendente"
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Ore per dipendente per mese"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Ore per dipendente per settimana"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Riga timesheet"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "Inserire righe"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Lavoro"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr "Context lavoro"
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "Durata"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "Durata"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "Annulla"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "Invio"
diff --git a/modules/timesheet/locale/lo.po b/modules/timesheet/locale/lo.po
new file mode 100644
index 0000000000..47bd6d36f3
--- /dev/null
+++ b/modules/timesheet/locale/lo.po
@@ -0,0 +1,389 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "ກຳນົດເວລາ"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "ພະນັກງານ"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "ວັນທີສິ້ນສຸດ"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "ວັນທີເລີ່ມ"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "ກຳນົດເວລາ"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "ພະນັກງານ"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "ເດືອນ"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "ປີ"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "ກຳນົດເວລາ"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "ພະນັກງານ"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "ອາທິດ"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "ປີ"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "ບໍລິສັດ"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "ວັນທີ"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "ຄຳອະທິບາຍ"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "ກຳນົດເວລາ"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "ພະນັກງານ"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr ""
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "ເຮັດວຽກ"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "ວັນທີ"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "ພະນັກງານ"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "ສູນການແພດ"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr "ກຳນົດເວລາຂອງຕາຕະລາງເວລາ"
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "ຊື່"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "ໜ້າວຽກເດີມ"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "ຕາຕະລາງເຮັດວຽກຈົບເວລາ"
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "ລາຍການຕາຕະລາງເຮັດວຽກ"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr "ຕາຕະລາງເຮັດວຽກເລີ້ມເວລາ"
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "ວຽກ"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "ແຕ່ວັນທີ"
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "ເຖິງວັນທີ"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr ""
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr ""
+
+#, fuzzy
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr "ເວລາທັງໝົດທີ່ໃຊ້ໃນໜ້າວຽກນີ້"
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr ""
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "ເຂົ້າແຖວຕາຕະລາງ"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Timesheet Lines"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr "ກຳນົດເວລາຂອງ \"%(line)s\" ຕ້ອງເປັນບວກ"
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr "ສຳນັກງານເດີມຕ້ອງບໍ່ຊໍ້າກັນ."
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Configuration"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "ເຂົ້າແຖວຕາຕະລາງ"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Reporting"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Timesheet Administration"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "ຊົ່ວໂມງຕໍ່ພະນັກງານຜູ້ນື່ງ"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr "ຕົວຈິງຊົ່ວໂມງຕໍ່ພະນັກງານ"
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "ຊົ່ວໂມງຕໍ່ພະນັກງານຜູ້ນື່ງຕໍ່ເດືອນ"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "ຊົ່ວໂມງຕໍ່ພະນັກງານຜູ້ນື່ງຕໍ່ອາທິດ"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "ຖັນແຖນຕາຕະລາງເຮັດວຽກ"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "ເຂົ້າແຖວຕາຕະລາງ"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "ເຮັດວຽກ"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr "ວຽກຕົວຈິງ"
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "ຕາຕະລາງເຮັດວຽກ"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "ກຳນົດເວລາ"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "ກຳນົດເວລາ"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "ຍົກເລີກ"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "ເຂົ້າໄປ"
diff --git a/modules/timesheet/locale/lt.po b/modules/timesheet/locale/lt.po
new file mode 100644
index 0000000000..d59435b1e1
--- /dev/null
+++ b/modules/timesheet/locale/lt.po
@@ -0,0 +1,378 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "Pabaigos data"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "Pradžios data"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr ""
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Organizacija"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr ""
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Works"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Organizacija"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Namu"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Timesheet Lines"
+
+#, fuzzy
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Timesheet Lines"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Works"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr ""
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr ""
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr ""
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Timesheet Lines"
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Nuostatos"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Ataskaitos"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Timesheet Administration"
+
+#, fuzzy
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Timesheet Lines"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Works"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr ""
diff --git a/modules/timesheet/locale/nl.po b/modules/timesheet/locale/nl.po
new file mode 100644
index 0000000000..f33e45c776
--- /dev/null
+++ b/modules/timesheet/locale/nl.po
@@ -0,0 +1,369 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Duur"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "Werknemer"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "Eind datum"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "Start datum"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "Duur"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "Werknemer"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "Maand"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "Jaar"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Duur"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "Werknemer"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "Week"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "Jaar"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Bedrijf"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Datum"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Omschrijving"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Duur"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "Werknemer"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr "UUID"
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Werk"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Datum"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Werknemer"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Bedrijf"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr "Duur"
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Naam"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "Oorsprong"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Einde urenstaat"
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Tijdregistratieregels"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr "Start urenstaat"
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Werk"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "Vanaf datum"
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "Tot datum"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr "Het bedrijf waarin de tijd wordt besteed."
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr "Wanneer de tijd is besteed."
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr "Aanvullende omschrijving van het verrichte werk."
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr "De werknemer die de tijd spendeerde."
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr "Het werk waaraan de tijd wordt besteed."
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr "Wanneer de tijd is besteed."
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr "De werknemer die de tijd spendeerde."
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr "Koppel het werk aan het bedrijf."
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr "Totale tijd besteed aan dit werk."
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr "De hoofdidentificatie van het werk."
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr "Gebruik om de bestede tijd te relateren aan andere records."
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr "Beperk het toevoegen van regels na de datum."
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr "Tijd besteed aan dit werk."
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr "Beperk het toevoegen van regels vóór de datum."
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr "Houd geen rekening met regels vóór de datum."
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr "Houd geen rekening met regels na de datum."
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Uren per werknemer"
+
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Uren per werknemer per maand"
+
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Uren per werknemer per week"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Voer urenstaat in"
+
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "Regels"
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Tijdregistratieregels"
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Werkzaamheden"
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Werkzaamheden"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr "Alles"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr "Open"
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr "De duur van regel \"%(line)s\" moet positief zijn."
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr "De UUID van de urenstaatregel moet uniek zijn."
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+"De bedrijven gekoppeld aan het werk \"%(work)s\" en de oorsprong ervan "
+"verschillen."
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr "De oorsprong van het werk moet uniek zijn per bedrijf."
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr "Elke medewerkers uren"
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr "Eigen medewerkersuren"
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr "Eigen urenstaatregel"
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr "Elke tijdsregistratie regel"
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr "Gebruiker in bedrijven"
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr "Gebruiker in het bedrijf"
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Instellingen"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Uren per werknemer"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Uren per werknemer per maand"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Uren per werknemer per week"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Voer urenstaat in"
+
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "Regels"
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Rapportage"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Tijdsregistratie"
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Werken"
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Werken"
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Tijdsregistratie administratie"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Uren per werknemer"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr "Context uren per werknemer"
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Uren per werknemer per maand"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Uren per werknemer per week"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Tijdregistratieregel"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "Voer regels in"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Werk"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr "Werk context"
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Tijdsregistratie"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "Duur"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "Duur"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "Annuleer"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "Invoeren"
diff --git a/modules/timesheet/locale/pl.po b/modules/timesheet/locale/pl.po
new file mode 100644
index 0000000000..5406a7cf10
--- /dev/null
+++ b/modules/timesheet/locale/pl.po
@@ -0,0 +1,383 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Czas trwania"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "Pracownik"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "Data ukończenia"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "Data rozpoczęcia"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "Czas trwania"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "Pracownik"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "Miesiąc"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "Rok"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Czas trwania"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "Pracownik"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "Tydzień"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "Rok"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Firma"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Opis"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Czas trwania"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "Pracownik"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr ""
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Praca"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Pracownik"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Firma"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr ""
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Nazwa"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "Źródło"
+
+#, fuzzy
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Timesheet Lines"
+
+#, fuzzy
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Timesheet Lines"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr ""
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Praca"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "Od dnia"
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "Do dnia"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr ""
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr ""
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr "Całkowity czas pracy"
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr ""
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Timesheet Lines"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Konfiguracja"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Reporting"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Timesheet Administration"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Godziny wg pracownika"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr ""
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Godziny wg pracownika na miesiąc"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Godziny wg pracownika na tydzień"
+
+#, fuzzy
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Timesheet Lines"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr ""
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Praca"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "Czas trwania"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "Czas trwania"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "Anuluj"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "Wprowadź"
diff --git a/modules/timesheet/locale/pt.po b/modules/timesheet/locale/pt.po
new file mode 100644
index 0000000000..8796986672
--- /dev/null
+++ b/modules/timesheet/locale/pt.po
@@ -0,0 +1,383 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Duração"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "Empregado"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "Data de término"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "Data de início"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "Duração"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "Empregado"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "Mês"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "Ano"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Duração"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "Empregado"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "Semana"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "Ano"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Descrição"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Duração"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "Empregado"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr ""
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Trabalho"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Empregado"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr "Duração do Horário de Trabalho"
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Nome"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "Origem"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Fim do Horário de Trabalho"
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Linhas do Horário de Trabalho"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr "Início do Horário de Trabalho"
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Trabalho"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "Desde a Data"
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "À Data"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr "A empresa à qual o tempo é gasto."
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr "Quando o tempo é gasto."
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr "Descrição adicional do trabalho feito."
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr "O empregado que gasta o tempo."
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr "O trabalho no qual o tempo é gasto."
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr "Quando o tempo é gasto."
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr "O empregado que gasta o tempo."
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr "Faça com que o trabalho pertença à empresa."
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr "Tempo total gasto neste trabalho."
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr "O identificador principal do trabalho."
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr "Use para relacionar o tempo gasto a outros registros."
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr "Restringe a adição de lançamentos após a data."
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr "Tempo gasto neste trabalho."
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr "Restringe a adição de lançamentos antes da data."
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr "Não considere lançamentos antes da data."
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr "Não considere lançamentos após a data."
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Digite Quadro de Horários"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "Inserir as Linhas"
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Linhas do Horário de Trabalho"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr "A duração da linha \"%(line)s\" deve ser positiva."
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr "A UUID da linha do horário de trabalho deve ser única."
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr "A origem deve ser única por empresa."
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Configuration"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Digite Quadro de Horários"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "Inserir as Linhas"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Reporting"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Quadro de Horários"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Administração do Quadro de Horários"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Horas por Empregado"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr "Contexto das Horas por Empregado"
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Horas por Empregado por Semana"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Horas por empregado por semana"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Linha de Horário de Trabalho"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "Inserir as Linhas"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Trabalho"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr "Contexto do Trabalho"
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Quadro de Horários"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "Duração"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "Duração"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "Inserir"
diff --git a/modules/timesheet/locale/ro.po b/modules/timesheet/locale/ro.po
new file mode 100644
index 0000000000..ed5c9415ec
--- /dev/null
+++ b/modules/timesheet/locale/ro.po
@@ -0,0 +1,367 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr ""
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Companie"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Descriere"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr ""
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr ""
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Angajat"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Companie"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr ""
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "Origine"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr ""
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr ""
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr ""
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr ""
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr ""
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr ""
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr ""
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Configurare"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Raportare"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr ""
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr ""
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr ""
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr ""
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr ""
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr ""
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr ""
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr ""
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr ""
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr ""
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr ""
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr ""
diff --git a/modules/timesheet/locale/ru.po b/modules/timesheet/locale/ru.po
new file mode 100644
index 0000000000..1ebef3e91e
--- /dev/null
+++ b/modules/timesheet/locale/ru.po
@@ -0,0 +1,400 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+#, fuzzy
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Продолжительность"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "Сотрудник"
+
+#, fuzzy
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "Дата окончания"
+
+#, fuzzy
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "Дата начала"
+
+#, fuzzy
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "Продолжительность"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "Сотрудник"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "Месяц"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "Год"
+
+#, fuzzy
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Продолжительность"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "Сотрудник"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "Неделя"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "Год"
+
+#, fuzzy
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Учет.орг."
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Дата"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Описание"
+
+#, fuzzy
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Продолжительность"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "Сотрудник"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr ""
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Работа"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Дата"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Сотрудник"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Организация"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr ""
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Наименование"
+
+#, fuzzy
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "Первоисточник"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Конечная дата табеля"
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Строки табеля"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr "Начальная дата табеля"
+
+#, fuzzy
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Работа"
+
+#, fuzzy
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "Начальная дата"
+
+#, fuzzy
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "Конечная дата"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr ""
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr ""
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr ""
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "Ввод строк"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Timesheet Lines"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Работы"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Configuration"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Часы на сотрудника"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "Ввод строк"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Reporting"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Работы"
+
+#, fuzzy
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Timesheet Administration"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Часы на сотрудника"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr ""
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Часы на сотрудника в месяц"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Часы на сотрудника в неделю"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Строка табеля"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "Ввод строк"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Работа"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Табель"
+
+#, fuzzy
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "Продолжительность"
+
+#, fuzzy
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "Продолжительность"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "Отменить"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "Ввод"
diff --git a/modules/timesheet/locale/sl.po b/modules/timesheet/locale/sl.po
new file mode 100644
index 0000000000..61ec29e1d9
--- /dev/null
+++ b/modules/timesheet/locale/sl.po
@@ -0,0 +1,388 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Trajanje"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "Zaposlenec"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "Konec"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "Začetek"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "Trajanje"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "Zaposlenec"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "Mesec"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "Leto"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Trajanje"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "Zaposlenec"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "Teden"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "Leto"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Družba"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Datum"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Opis"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Trajanje"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "Zaposlenec"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr ""
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Naloga"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Datum"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Zaposlenec"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Družba"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr "Trajanje"
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Naziv"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "Poreklo"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Konec evidence"
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Evidenca dela"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr "Začetek evidence"
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Naloga"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "Od"
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "Do"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr "Družba, za katero se evidentira čas."
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr "Dan evidentiranja časa."
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr "Dodaten opis opravljene naloge."
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr "Zaposlenec, katerega čas se evidentira."
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr "Naloga, za katero se evidentira čas."
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr "Dan evidentiranja časa."
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr "Zaposlenec, katerega čas se evidentira."
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr "Poveži nalogo z družbo."
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr "Skupen čas, porabljen na nalogi."
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr "Glavni identifikator naloge."
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr "Povezuje porabljen čas z drugimi zapisi."
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr "Evidentiranje časa po tem datumu je onemogočeno."
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr "Evidentiranje časa, porabljenega na nalogi."
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr "Evidentiranje časa pred tem datumom je onemogočeno."
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr "Evidenca časa pred tem datumom se ne upošteva."
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr "Evidenca časa po tem datumu se ne upošteva."
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "Vnos postavk"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Timesheet Lines"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr "Trajanje na postavki \"%(line)s\" mora biti nenegativno."
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr "Poreklo mora biti unikatno po družbi."
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Configuration"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "Vnos postavk"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Reporting"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Works"
+
+#, fuzzy
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Timesheet Administration"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Ure po zaposlencu"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr "Ure po kontekstu zaposlenca"
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Mesečne ure po zaposlencu"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Tedenske ure po zaposlencu"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Evidenca dela"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "Vnos postavk"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Naloga"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr "Kontekst naloge"
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Evidenca dela"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "Trajanje"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "Trajanje"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "Prekliči"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "Vnos"
diff --git a/modules/timesheet/locale/tr.po b/modules/timesheet/locale/tr.po
new file mode 100644
index 0000000000..07baca0fb9
--- /dev/null
+++ b/modules/timesheet/locale/tr.po
@@ -0,0 +1,379 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr ""
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr ""
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr ""
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Works"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr ""
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Timesheet Lines"
+
+#, fuzzy
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Timesheet Lines"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Works"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr ""
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr ""
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr ""
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr ""
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr ""
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr ""
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr ""
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Timesheet Lines"
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr "İş \"%(line)s\" süresi pozitif olmalı"
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr "Kök her firma için özgün olmalı."
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Configuration"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Enter Timesheet"
+
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Reporting"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Works"
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Timesheet Administration"
+
+#, fuzzy
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Hours per Employee"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Hours per Employee per Month"
+
+#, fuzzy
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Hours per Employee per Week"
+
+#, fuzzy
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Timesheet Lines"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr ""
+
+#, fuzzy
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Works"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr ""
+
+#, fuzzy
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Timesheet"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr ""
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr ""
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr ""
diff --git a/modules/timesheet/locale/uk.po b/modules/timesheet/locale/uk.po
new file mode 100644
index 0000000000..8e5115fd6f
--- /dev/null
+++ b/modules/timesheet/locale/uk.po
@@ -0,0 +1,368 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "Тривалість"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "Працівник"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "Кінцева дата"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "Початкова дата"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "Тривалість"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "Працівник"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "Місяць"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "Рік"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "Тривалість"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "Працівник"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "Тиждень"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "Рік"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "Компанія"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "Дата"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "Опис"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "Тривалість"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "Працівник"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr "UUID"
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "Робота"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "Дата"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "Працівник"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "Компанія"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr "Тривалість табеля"
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "Назва"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "Походження"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "Кінець табеля"
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "Рядки табеля"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr "Початок табеля"
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "Робота"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "З дати"
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "До дати"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr "Компанія, на яку витрачається час."
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr "Коли час витрачено."
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr "Додатковий опис виконаної роботи."
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr "Працівник, який витрачає час."
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr "Робота, на яку витрачається час."
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr "Коли час витрачено."
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr "Працівник, який витрачає час."
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr "Зробіть роботу належною компанії."
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr "Загальний час, витрачений на цю роботу."
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr "Основний ідентифікатор роботи."
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr "Використовуйте, щоб пов'язати витрачений час з іншими записами."
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr "Обмежити додавання рядків після дати."
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr "Витратити час на цю роботу."
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr "Обмежити додавання рядків перед датою."
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr "Не брати до уваги рядки перед датою."
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr "Не брати до уваги рядки після дати."
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "Години на одного працівника"
+
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "Години на одного працівника на місяць"
+
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "Години на одного працівника на тиждень"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "Ввести табель"
+
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "Рядки"
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "Рядки табеля"
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "Роботи"
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "Роботи"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr "Усі"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr "Відкриті"
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr "Тривалість рядка \"%(line)s\" має бути додатною."
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr "UUID рядка табеля має бути унікальним."
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr ""
+"Компанії, пов'язані з роботою \"%(work)s\" та її походження відрізняються."
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr "Походження роботи має бути унікальним для компанії."
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr "Будь-які години працівника"
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr "Власні години працівника"
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr "Власний рядок табеля"
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr "Будь-який рядок табеля"
+
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr "Користувач у компаніях"
+
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr "Користувач у компаніях"
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "Налаштування"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "Години на одного працівника"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "Години на одного працівника на місяць"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "Години на одного працівника на тиждень"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "Ввести табель"
+
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "Рядки"
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "Звітність"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "Табель"
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "Роботи"
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "Роботи"
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "Адміністрування табелів"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "Години на одного працівника"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr "Контекст годин на одного працівника"
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "Години на одного працівника на місяць"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "Години на одного працівника на тиждень"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "Рядок табеля"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "Введіть рядки"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "Робота"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr "Контекст роботи"
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "Табель"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "Тривалість"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "Тривалість"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "Скасувати"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "Введіть"
diff --git a/modules/timesheet/locale/zh_CN.po b/modules/timesheet/locale/zh_CN.po
new file mode 100644
index 0000000000..6ec6e81869
--- /dev/null
+++ b/modules/timesheet/locale/zh_CN.po
@@ -0,0 +1,372 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:timesheet.hours_employee,duration:"
+msgid "Duration"
+msgstr "持续时间"
+
+msgctxt "field:timesheet.hours_employee,employee:"
+msgid "Employee"
+msgstr "雇员"
+
+msgctxt "field:timesheet.hours_employee.context,end_date:"
+msgid "End Date"
+msgstr "结束日期"
+
+msgctxt "field:timesheet.hours_employee.context,start_date:"
+msgid "Start Date"
+msgstr "开始日期"
+
+msgctxt "field:timesheet.hours_employee_monthly,duration:"
+msgid "Duration"
+msgstr "持续时间"
+
+msgctxt "field:timesheet.hours_employee_monthly,employee:"
+msgid "Employee"
+msgstr "雇员"
+
+msgctxt "field:timesheet.hours_employee_monthly,month:"
+msgid "Month"
+msgstr "月"
+
+msgctxt "field:timesheet.hours_employee_monthly,year:"
+msgid "Year"
+msgstr "年"
+
+msgctxt "field:timesheet.hours_employee_weekly,duration:"
+msgid "Duration"
+msgstr "持续时间"
+
+msgctxt "field:timesheet.hours_employee_weekly,employee:"
+msgid "Employee"
+msgstr "雇员"
+
+msgctxt "field:timesheet.hours_employee_weekly,week:"
+msgid "Week"
+msgstr "周"
+
+msgctxt "field:timesheet.hours_employee_weekly,year:"
+msgid "Year"
+msgstr "年"
+
+msgctxt "field:timesheet.line,company:"
+msgid "Company"
+msgstr "公司"
+
+msgctxt "field:timesheet.line,date:"
+msgid "Date"
+msgstr "日期"
+
+msgctxt "field:timesheet.line,description:"
+msgid "Description"
+msgstr "描述"
+
+msgctxt "field:timesheet.line,duration:"
+msgid "Duration"
+msgstr "持续时间"
+
+msgctxt "field:timesheet.line,employee:"
+msgid "Employee"
+msgstr "雇员"
+
+msgctxt "field:timesheet.line,uuid:"
+msgid "UUID"
+msgstr "UUID"
+
+msgctxt "field:timesheet.line,work:"
+msgid "Work"
+msgstr "工作"
+
+msgctxt "field:timesheet.line.enter.start,date:"
+msgid "Date"
+msgstr "日期"
+
+msgctxt "field:timesheet.line.enter.start,employee:"
+msgid "Employee"
+msgstr "雇员"
+
+msgctxt "field:timesheet.work,company:"
+msgid "Company"
+msgstr "公司"
+
+msgctxt "field:timesheet.work,duration:"
+msgid "Timesheet Duration"
+msgstr "时间表持续时间"
+
+msgctxt "field:timesheet.work,name:"
+msgid "Name"
+msgstr "名称"
+
+msgctxt "field:timesheet.work,origin:"
+msgid "Origin"
+msgstr "来源"
+
+msgctxt "field:timesheet.work,timesheet_end_date:"
+msgid "Timesheet End"
+msgstr "时间表结束"
+
+msgctxt "field:timesheet.work,timesheet_lines:"
+msgid "Timesheet Lines"
+msgstr "时间表明细"
+
+msgctxt "field:timesheet.work,timesheet_start_date:"
+msgid "Timesheet Start"
+msgstr "时间表开始"
+
+msgctxt "field:timesheet.work,work:"
+msgid "Work"
+msgstr "工作"
+
+msgctxt "field:timesheet.work.context,from_date:"
+msgid "From Date"
+msgstr "从日期"
+
+msgctxt "field:timesheet.work.context,to_date:"
+msgid "To Date"
+msgstr "到日期"
+
+msgctxt "help:timesheet.line,company:"
+msgid "The company on which the time is spent."
+msgstr "消耗时间的公司."
+
+msgctxt "help:timesheet.line,date:"
+msgid "When the time is spent."
+msgstr "时间消耗的时候."
+
+msgctxt "help:timesheet.line,description:"
+msgid "Additional description of the work done."
+msgstr "完成工作的附加说明."
+
+msgctxt "help:timesheet.line,employee:"
+msgid "The employee who spends the time."
+msgstr "消耗时间的雇员."
+
+msgctxt "help:timesheet.line,work:"
+msgid "The work on which the time is spent."
+msgstr "消耗时间的工作."
+
+msgctxt "help:timesheet.line.enter.start,date:"
+msgid "When the time is spent."
+msgstr "消耗时间的时候."
+
+msgctxt "help:timesheet.line.enter.start,employee:"
+msgid "The employee who spends the time."
+msgstr "消耗时间的雇员."
+
+msgctxt "help:timesheet.work,company:"
+msgid "Make the work belong to the company."
+msgstr "让这项工作属于公司."
+
+msgctxt "help:timesheet.work,duration:"
+msgid "Total time spent on this work."
+msgstr "消耗在这项工作上的总时间."
+
+msgctxt "help:timesheet.work,name:"
+msgid "The main identifier of the work."
+msgstr "工作的主标识符."
+
+msgctxt "help:timesheet.work,origin:"
+msgid "Use to relate the time spent to other records."
+msgstr "用于将所花费的时间与其他记录相关联."
+
+msgctxt "help:timesheet.work,timesheet_end_date:"
+msgid "Restrict adding lines after the date."
+msgstr "限制只允许在日期之后添加行."
+
+msgctxt "help:timesheet.work,timesheet_lines:"
+msgid "Spend time on this work."
+msgstr "此项工作消耗的时间."
+
+msgctxt "help:timesheet.work,timesheet_start_date:"
+msgid "Restrict adding lines before the date."
+msgstr "限制只允许在日期之前添加行."
+
+msgctxt "help:timesheet.work.context,from_date:"
+msgid "Do not take into account lines before the date."
+msgstr "不考虑日期之前的行."
+
+msgctxt "help:timesheet.work.context,to_date:"
+msgid "Do not take into account lines after the date."
+msgstr "不考虑日期之后的行."
+
+msgctxt "model:ir.action,name:act_hours_employee_form"
+msgid "Hours per Employee"
+msgstr "雇员工作小时数"
+
+msgctxt "model:ir.action,name:act_hours_employee_monthly_form"
+msgid "Hours per Employee per Month"
+msgstr "雇员月工作小时数"
+
+msgctxt "model:ir.action,name:act_hours_employee_weekly_form"
+msgid "Hours per Employee per Week"
+msgstr "雇员周工作小时数"
+
+msgctxt "model:ir.action,name:act_line_enter"
+msgid "Enter Timesheet"
+msgstr "输入时间表"
+
+#, fuzzy
+msgctxt "model:ir.action,name:act_line_form"
+msgid "Lines"
+msgstr "输入行"
+
+msgctxt "model:ir.action,name:act_line_form_work"
+msgid "Timesheet Lines"
+msgstr "时间表明细"
+
+msgctxt "model:ir.action,name:act_work_list"
+msgid "Works"
+msgstr "工作"
+
+msgctxt "model:ir.action,name:act_work_report"
+msgid "Works"
+msgstr "工作"
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_all"
+msgid "All"
+msgstr ""
+
+msgctxt "model:ir.action.act_window.domain,name:act_work_list_domain_open"
+msgid "Open"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_line_duration_positive"
+msgid "The duration of line \"%(line)s\" must be positive."
+msgstr "持续时间明细 \"%(line)s\" 必须为正."
+
+msgctxt "model:ir.message,text:msg_line_uuid_unique"
+msgid "The UUID of timesheet line must be unique."
+msgstr "时间表的 UUID 不能重复."
+
+msgctxt "model:ir.message,text:msg_work_company_different_origin"
+msgid "The companies associated with work \"%(work)s\" and its origin differ."
+msgstr "工作\"%(work)s\"关联的公司与其来源关联的公司不一致."
+
+msgctxt "model:ir.message,text:msg_work_origin_unique_company"
+msgid "Work origin must be unique by company."
+msgstr "工作来源必须按公司唯一."
+
+msgctxt "model:ir.rule.group,name:rule_group_hours_employee_admin"
+msgid "Any employee hours"
+msgstr "任意雇员工时"
+
+#, fuzzy
+msgctxt "model:ir.rule.group,name:rule_group_hours_employees"
+msgid "Own employee hours"
+msgstr "自有雇员工时"
+
+msgctxt "model:ir.rule.group,name:rule_group_line"
+msgid "Own timesheet line"
+msgstr "自有雇员时间表明细"
+
+msgctxt "model:ir.rule.group,name:rule_group_line_admin"
+msgid "Any timesheet line"
+msgstr "任意雇员工时间表明细"
+
+#, fuzzy
+msgctxt "model:ir.rule.group,name:rule_group_line_companies"
+msgid "User in companies"
+msgstr "公司中的用户"
+
+#, fuzzy
+msgctxt "model:ir.rule.group,name:rule_group_work_companies"
+msgid "User in companies"
+msgstr "公司中的用户"
+
+msgctxt "model:ir.ui.menu,name:menu_configuration"
+msgid "Configuration"
+msgstr "设置"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee"
+msgid "Hours per Employee"
+msgstr "雇员工作小时数"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_monthly"
+msgid "Hours per Employee per Month"
+msgstr "雇员月工作小时数"
+
+msgctxt "model:ir.ui.menu,name:menu_hours_employee_open_weekly"
+msgid "Hours per Employee per Week"
+msgstr "雇员周工作小时数"
+
+msgctxt "model:ir.ui.menu,name:menu_line_enter"
+msgid "Enter Timesheet"
+msgstr "输入时间表"
+
+#, fuzzy
+msgctxt "model:ir.ui.menu,name:menu_line_form"
+msgid "Lines"
+msgstr "输入行"
+
+msgctxt "model:ir.ui.menu,name:menu_reporting"
+msgid "Reporting"
+msgstr "报表"
+
+msgctxt "model:ir.ui.menu,name:menu_timesheet"
+msgid "Timesheet"
+msgstr "时间表"
+
+msgctxt "model:ir.ui.menu,name:menu_work_list"
+msgid "Works"
+msgstr "工作"
+
+msgctxt "model:ir.ui.menu,name:menu_work_report"
+msgid "Works"
+msgstr "工作"
+
+msgctxt "model:res.group,name:group_timesheet_admin"
+msgid "Timesheet Administration"
+msgstr "时间表管理"
+
+msgctxt "model:timesheet.hours_employee,name:"
+msgid "Hours per Employee"
+msgstr "雇员工作小时数"
+
+msgctxt "model:timesheet.hours_employee.context,name:"
+msgid "Hours per Employee Context"
+msgstr "雇员的工作时间"
+
+msgctxt "model:timesheet.hours_employee_monthly,name:"
+msgid "Hours per Employee per Month"
+msgstr "雇员月工作小时数"
+
+msgctxt "model:timesheet.hours_employee_weekly,name:"
+msgid "Hours per Employee per Week"
+msgstr "雇员周工作小时数"
+
+msgctxt "model:timesheet.line,name:"
+msgid "Timesheet Line"
+msgstr "时间表明细"
+
+msgctxt "model:timesheet.line.enter.start,name:"
+msgid "Enter Lines"
+msgstr "输入行"
+
+msgctxt "model:timesheet.work,name:"
+msgid "Work"
+msgstr "工作"
+
+msgctxt "model:timesheet.work.context,name:"
+msgid "Work Context"
+msgstr "工作环境"
+
+msgctxt "selection:res.user.application,application:"
+msgid "Timesheet"
+msgstr "时间表"
+
+msgctxt "view:timesheet.hours_employee:"
+msgid "Duration"
+msgstr "持续时间"
+
+msgctxt "view:timesheet.line:"
+msgid "Duration"
+msgstr "持续时间"
+
+msgctxt "wizard_button:timesheet.line.enter,start,end:"
+msgid "Cancel"
+msgstr "取消"
+
+msgctxt "wizard_button:timesheet.line.enter,start,enter:"
+msgid "Enter"
+msgstr "输入"
diff --git a/modules/timesheet/message.xml b/modules/timesheet/message.xml
new file mode 100644
index 0000000000..d015f75e0a
--- /dev/null
+++ b/modules/timesheet/message.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+ The companies associated with work "%(work)s" and its origin differ.
+
+
+ The duration of line "%(line)s" must be positive.
+
+
+ Work origin must be unique by company.
+
+
+ The UUID of timesheet line must be unique.
+
+
+
diff --git a/modules/timesheet/routes.py b/modules/timesheet/routes.py
new file mode 100644
index 0000000000..daae774aee
--- /dev/null
+++ b/modules/timesheet/routes.py
@@ -0,0 +1,136 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import datetime
+
+from werkzeug.exceptions import abort
+from werkzeug.wrappers import Response
+
+from trytond.protocols.wrappers import (
+ allow_null_origin, user_application, with_pool, with_transaction)
+from trytond.transaction import Transaction
+from trytond.wsgi import app
+
+timesheet_application = user_application('timesheet')
+
+
+@app.route('//timesheet/employees', methods=['GET'])
+@allow_null_origin
+@with_pool
+@with_transaction()
+@timesheet_application
+def timesheet_employees(request, pool):
+ User = pool.get('res.user')
+ user = User(Transaction().user)
+ return [{'id': e.id, 'name': e.rec_name} for e in user.employees]
+
+
+@app.route('//timesheet/employee//works',
+ methods=['GET'])
+@allow_null_origin
+@with_pool
+@with_transaction()
+@timesheet_application
+def timesheet_works(request, pool, employee):
+ Work = pool.get('timesheet.work')
+ Employee = pool.get('company.employee')
+ employee = Employee(employee)
+ with Transaction().set_context(
+ company=employee.company.id, employee=employee.id):
+ works = Work.search([
+ ('company', '=', employee.company.id),
+ ])
+ return sorted(({
+ 'id': w.id,
+ 'name': w.rec_name,
+ 'start': (w.timesheet_start_date.strftime('%Y-%m-%d')
+ if w.timesheet_start_date else None),
+ 'end': (w.timesheet_end_date.strftime('%Y-%m-%d')
+ if w.timesheet_end_date else None),
+ } for w in works),
+ key=lambda w: w['name'].lower())
+
+
+@app.route('//timesheet/employee//lines/',
+ methods=['GET'])
+@allow_null_origin
+@with_pool
+@with_transaction()
+@timesheet_application
+def timesheet_lines(request, pool, employee, date):
+ User = pool.get('res.user')
+ Employee = pool.get('company.employee')
+ Line = pool.get('timesheet.line')
+
+ employee = Employee(employee)
+ date = datetime.datetime.strptime(date, '%Y-%m-%d').date()
+ user = User(Transaction().user)
+ if employee not in user.employees:
+ abort(403)
+
+ with Transaction().set_context(
+ company=employee.company.id, employee=employee.id):
+ lines = Line.search([
+ ('employee', '=', employee.id),
+ ('date', '=', date),
+ ],
+ order=[('id', 'ASC')])
+ return [l.to_json() for l in lines]
+
+
+@app.route('//timesheet/line/',
+ methods=['PUT', 'DELETE'])
+@app.route('//timesheet/line', methods=['POST'])
+@allow_null_origin
+@with_pool
+@with_transaction()
+@timesheet_application
+def timesheet(request, pool, line=None):
+ Line = pool.get('timesheet.line')
+ User = pool.get('res.user')
+ Employee = pool.get('company.employee')
+ if request.method in {'POST', 'PUT'}:
+ data = request.parsed_data.copy()
+
+ if not line and data.get('uuid'):
+ lines = Line.search([
+ ('uuid', '=', data['uuid']),
+ ])
+ if lines:
+ line, = lines
+
+ if 'employee' in data:
+ employee = Employee(data['employee'])
+ data['company'] = employee.company.id
+ else:
+ employee = User(Transaction().user).employee
+ if 'date' in data:
+ data['date'] = datetime.datetime.strptime(
+ data['date'], '%Y-%m-%d').date()
+ if 'duration' in data:
+ data['duration'] = datetime.timedelta(
+ seconds=data['duration'])
+
+ for extra in set(data) - set(Line._fields):
+ del data[extra]
+
+ with Transaction().set_context(
+ company=employee.company.id, employee=employee.id):
+ if not line:
+ line, = Line.create([data])
+ else:
+ lines = Line.search([('id', '=', int(line))])
+ if not lines:
+ return Response(None, 204)
+ line, = lines
+ Line.write(lines, data)
+ return line.to_json()
+ else:
+ with Transaction().set_user(0):
+ lines = Line.search([('id', '=', line)])
+ if lines:
+ line, = lines
+ with Transaction().set_context(
+ company=line.company.id, employee=line.employee.id):
+ lines = Line.search([('id', '=', line.id)])
+ Line.delete(lines)
+ return Response(None, 204)
diff --git a/modules/timesheet/setup.py b/modules/timesheet/setup.py
new file mode 100755
index 0000000000..4fa02af479
--- /dev/null
+++ b/modules/timesheet/setup.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname, slice=None):
+ content = io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+ if slice:
+ content = '\n'.join(content.splitlines()[slice])
+ return content
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_timesheet'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = ['python-sql', 'werkzeug']
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module with timesheets',
+ long_description=read('README.rst', slice=slice(0, -5)),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/timesheet',
+ },
+ keywords='tryton timesheet',
+ package_dir={'trytond.modules.timesheet': '.'},
+ packages=(
+ ['trytond.modules.timesheet']
+ + ['trytond.modules.timesheet.%s' % p for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.timesheet': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', 'icons/*.svg']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'Intended Audience :: Manufacturing',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ timesheet = trytond.modules.timesheet
+ """,
+ )
diff --git a/modules/timesheet/tests/__init__.py b/modules/timesheet/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/timesheet/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/timesheet/tests/test_module.py b/modules/timesheet/tests/test_module.py
new file mode 100644
index 0000000000..6664d524a9
--- /dev/null
+++ b/modules/timesheet/tests/test_module.py
@@ -0,0 +1,13 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.modules.company.tests import CompanyTestMixin
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class TimesheetTestCase(CompanyTestMixin, ModuleTestCase):
+ 'Test Timesheet module'
+ module = 'timesheet'
+
+
+del ModuleTestCase
diff --git a/modules/timesheet/timesheet.xml b/modules/timesheet/timesheet.xml
new file mode 100644
index 0000000000..9fc2b9f481
--- /dev/null
+++ b/modules/timesheet/timesheet.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+ Timesheet Administration
+
+
+
+
+
+
+
+ tryton-timesheet
+ icons/tryton-timesheet.svg
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/timesheet/tox.ini b/modules/timesheet/tox.ini
new file mode 100644
index 0000000000..fd57405bd4
--- /dev/null
+++ b/modules/timesheet/tox.ini
@@ -0,0 +1,16 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+commands =
+ coverage run --include=./**/timesheet/* -m unittest discover -s tests
+ coverage report --include=./**/timesheet/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/timesheet/tryton.cfg b/modules/timesheet/tryton.cfg
new file mode 100644
index 0000000000..0a0a03b010
--- /dev/null
+++ b/modules/timesheet/tryton.cfg
@@ -0,0 +1,12 @@
+[tryton]
+version=6.7.0
+depends:
+ company
+ company_work_time
+ ir
+ res
+xml:
+ timesheet.xml
+ work.xml
+ line.xml
+ message.xml
diff --git a/modules/timesheet/user.py b/modules/timesheet/user.py
new file mode 100644
index 0000000000..7a5f143f6f
--- /dev/null
+++ b/modules/timesheet/user.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.pool import PoolMeta
+
+
+class UserApplication(metaclass=PoolMeta):
+ __name__ = 'res.user.application'
+
+ @classmethod
+ def __setup__(cls):
+ super(UserApplication, cls).__setup__()
+ cls.application.selection.append(('timesheet', 'Timesheet'))
diff --git a/modules/timesheet/view/hours_employee_context_form.xml b/modules/timesheet/view/hours_employee_context_form.xml
new file mode 100644
index 0000000000..029f1a04e5
--- /dev/null
+++ b/modules/timesheet/view/hours_employee_context_form.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/modules/timesheet/view/hours_employee_graph.xml b/modules/timesheet/view/hours_employee_graph.xml
new file mode 100644
index 0000000000..dceb3c3888
--- /dev/null
+++ b/modules/timesheet/view/hours_employee_graph.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/timesheet/view/hours_employee_monthly_tree.xml b/modules/timesheet/view/hours_employee_monthly_tree.xml
new file mode 100644
index 0000000000..254ec5a51b
--- /dev/null
+++ b/modules/timesheet/view/hours_employee_monthly_tree.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/timesheet/view/hours_employee_tree.xml b/modules/timesheet/view/hours_employee_tree.xml
new file mode 100644
index 0000000000..4b2f42967a
--- /dev/null
+++ b/modules/timesheet/view/hours_employee_tree.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
diff --git a/modules/timesheet/view/hours_employee_weekly_tree.xml b/modules/timesheet/view/hours_employee_weekly_tree.xml
new file mode 100644
index 0000000000..05dbf1941b
--- /dev/null
+++ b/modules/timesheet/view/hours_employee_weekly_tree.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/timesheet/view/line_enter_start_form.xml b/modules/timesheet/view/line_enter_start_form.xml
new file mode 100644
index 0000000000..b0702056f5
--- /dev/null
+++ b/modules/timesheet/view/line_enter_start_form.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/modules/timesheet/view/line_form.xml b/modules/timesheet/view/line_form.xml
new file mode 100644
index 0000000000..5175373a7b
--- /dev/null
+++ b/modules/timesheet/view/line_form.xml
@@ -0,0 +1,17 @@
+
+
+
diff --git a/modules/timesheet/view/line_tree.xml b/modules/timesheet/view/line_tree.xml
new file mode 100644
index 0000000000..9b7e392986
--- /dev/null
+++ b/modules/timesheet/view/line_tree.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/timesheet/view/work_context_form.xml b/modules/timesheet/view/work_context_form.xml
new file mode 100644
index 0000000000..39f1822f77
--- /dev/null
+++ b/modules/timesheet/view/work_context_form.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/modules/timesheet/view/work_form.xml b/modules/timesheet/view/work_form.xml
new file mode 100644
index 0000000000..8577da93a3
--- /dev/null
+++ b/modules/timesheet/view/work_form.xml
@@ -0,0 +1,19 @@
+
+
+
diff --git a/modules/timesheet/view/work_graph.xml b/modules/timesheet/view/work_graph.xml
new file mode 100644
index 0000000000..8dd66a2fb3
--- /dev/null
+++ b/modules/timesheet/view/work_graph.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/timesheet/view/work_list.xml b/modules/timesheet/view/work_list.xml
new file mode 100644
index 0000000000..d98a8694c2
--- /dev/null
+++ b/modules/timesheet/view/work_list.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/timesheet/view/work_list_report.xml b/modules/timesheet/view/work_list_report.xml
new file mode 100644
index 0000000000..2f0fff327e
--- /dev/null
+++ b/modules/timesheet/view/work_list_report.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/timesheet/work.py b/modules/timesheet/work.py
new file mode 100644
index 0000000000..53d90612a5
--- /dev/null
+++ b/modules/timesheet/work.py
@@ -0,0 +1,221 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import datetime
+
+from sql import Literal
+from sql.aggregate import Sum
+
+from trytond.i18n import gettext
+from trytond.model import ModelSQL, ModelStorage, ModelView, Unique, fields
+from trytond.pool import Pool
+from trytond.pyson import Bool, Eval, If
+from trytond.tools import grouped_slice, reduce_ids
+from trytond.transaction import Transaction
+
+from .exceptions import CompanyValidationError
+
+
+class Work(ModelSQL, ModelView):
+ 'Work'
+ __name__ = 'timesheet.work'
+ name = fields.Char('Name',
+ states={
+ 'invisible': Bool(Eval('origin')),
+ 'required': ~Eval('origin'),
+ },
+ help="The main identifier of the work.")
+ origin = fields.Reference('Origin', selection='get_origin',
+ states={
+ 'invisible': Bool(Eval('name')),
+ 'required': ~Eval('name'),
+ },
+ help="Use to relate the time spent to other records.")
+ duration = fields.Function(fields.TimeDelta('Timesheet Duration',
+ 'company_work_time', help="Total time spent on this work."),
+ 'get_duration')
+ timesheet_start_date = fields.Date('Timesheet Start',
+ domain=[
+ If(Eval('timesheet_start_date') & Eval('timesheet_end_date'),
+ ('timesheet_start_date', '<=', Eval('timesheet_end_date')),
+ ()),
+ ],
+ help="Restrict adding lines before the date.")
+ timesheet_end_date = fields.Date('Timesheet End',
+ domain=[
+ If(Eval('timesheet_start_date') & Eval('timesheet_end_date'),
+ ('timesheet_end_date', '>=', Eval('timesheet_start_date')),
+ ()),
+ ],
+ help="Restrict adding lines after the date.")
+ company = fields.Many2One(
+ 'company.company', "Company", required=True,
+ help="Make the work belong to the company.")
+ timesheet_lines = fields.One2Many('timesheet.line', 'work',
+ 'Timesheet Lines',
+ help="Spend time on this work.")
+ # Self referring field to use for aggregation in graph view
+ work = fields.Function(fields.Many2One('timesheet.work', 'Work'),
+ 'get_work')
+
+ @classmethod
+ def __setup__(cls):
+ super(Work, cls).__setup__()
+ t = cls.__table__()
+ cls._sql_constraints += [
+ ('origin_unique', Unique(t, t.origin, t.company),
+ 'timesheet.msg_work_origin_unique_company'),
+ ]
+
+ @classmethod
+ def __register__(cls, module_name):
+ table_h = cls.__table_handler__(module_name)
+ table = cls.__table__()
+ cursor = Transaction().connection.cursor()
+
+ super(Work, cls).__register__(module_name)
+
+ # Migration from 4.0: remove required on name
+ table_h.not_null_action('name', 'remove')
+
+ # Migration from 4.0: remove parent, left and right
+ if table_h.column_exist('parent'):
+ id2name = {}
+ id2parent = {}
+ cursor.execute(*table.select(
+ table.id, table.parent, table.name))
+ for id_, parent, name in cursor:
+ id2name[id_] = name
+ id2parent[id_] = parent
+
+ for id_, name in id2name.items():
+ parent = id2parent[id_]
+ while parent:
+ name = '%s\\%s' % (id2name[parent], name)
+ parent = id2parent[parent]
+ cursor.execute(*table.update(
+ [table.name], [name],
+ where=table.id == id_))
+ table_h.drop_column('parent')
+ table_h.drop_column('left')
+ table_h.drop_column('right')
+
+ # Migration from 4.0: remove timesheet_available
+ if table_h.column_exist('timesheet_available'):
+ cursor.execute(*table.delete(
+ where=table.timesheet_available == Literal(False)))
+ table_h.drop_column('timesheet_available')
+
+ @staticmethod
+ def default_company():
+ return Transaction().context.get('company')
+
+ @classmethod
+ def _get_origin(cls):
+ 'Return list of Model names for origin Reference'
+ return []
+
+ @classmethod
+ def get_origin(cls):
+ Model = Pool().get('ir.model')
+ get_name = Model.get_name
+ models = cls._get_origin()
+ return [('', '')] + [(m, get_name(m)) for m in models]
+
+ @classmethod
+ def get_duration(cls, works, name):
+ pool = Pool()
+ Line = pool.get('timesheet.line')
+ transaction = Transaction()
+ cursor = transaction.connection.cursor()
+ context = transaction.context
+
+ table_w = cls.__table__()
+ line = Line.__table__()
+ ids = [w.id for w in works]
+ durations = dict.fromkeys(ids, None)
+ where = Literal(True)
+ if context.get('from_date'):
+ where &= line.date >= context['from_date']
+ if context.get('to_date'):
+ where &= line.date <= context['to_date']
+ if context.get('employees'):
+ where &= line.employee.in_(context['employees'])
+
+ query_table = table_w.join(line, 'LEFT',
+ condition=line.work == table_w.id)
+
+ for sub_ids in grouped_slice(ids):
+ red_sql = reduce_ids(table_w.id, sub_ids)
+ cursor.execute(*query_table.select(table_w.id, Sum(line.duration),
+ where=red_sql & where,
+ group_by=table_w.id))
+ for work_id, duration in cursor:
+ # SQLite uses float for SUM
+ if duration and not isinstance(duration, datetime.timedelta):
+ duration = datetime.timedelta(seconds=duration)
+ durations[work_id] = duration
+ return durations
+
+ def get_work(self, name):
+ return self.id
+
+ def get_rec_name(self, name):
+ if isinstance(self.origin, ModelStorage):
+ return self.origin.rec_name
+ else:
+ return self.name
+
+ @classmethod
+ def search_rec_name(cls, name, clause):
+ if clause[1].startswith('!') or clause[1].startswith('not '):
+ bool_op = 'AND'
+ else:
+ bool_op = 'OR'
+ return [bool_op,
+ ('name',) + tuple(clause[1:]),
+ ] + [
+ ('origin.rec_name',) + tuple(clause[1:]) + (origin,)
+ for origin in cls._get_origin()]
+
+ @classmethod
+ def copy(cls, works, default=None):
+ if default is None:
+ default = {}
+ else:
+ default = default.copy()
+ default.setdefault('timesheet_lines', None)
+ return super(Work, cls).copy(works, default=default)
+
+ @classmethod
+ def validate(cls, works):
+ super(Work, cls).validate(works)
+ for work in works:
+ if work.origin and not work._validate_company():
+ raise CompanyValidationError(
+ gettext('timesheet.msg_work_company_different_origin',
+ work=work.rec_name))
+
+ def _validate_company(self):
+ return True
+
+ @classmethod
+ def search_global(cls, text):
+ for record, rec_name, icon in super(Work, cls).search_global(text):
+ icon = icon or 'tryton-clock'
+ yield record, rec_name, icon
+
+ @property
+ def hours(self):
+ if not self.duration:
+ return 0
+ return self.duration.total_seconds() / 60 / 60
+
+
+class WorkContext(ModelView):
+ 'Work Context'
+ __name__ = 'timesheet.work.context'
+ from_date = fields.Date('From Date',
+ help="Do not take into account lines before the date.")
+ to_date = fields.Date('To Date',
+ help="Do not take into account lines after the date.")
diff --git a/modules/timesheet/work.xml b/modules/timesheet/work.xml
new file mode 100644
index 0000000000..5c8a306437
--- /dev/null
+++ b/modules/timesheet/work.xml
@@ -0,0 +1,123 @@
+
+
+
+
+
+ timesheet.work
+ form
+ work_form
+
+
+ timesheet.work
+ tree
+
+ work_list
+
+
+ timesheet.work
+ tree
+
+ work_list_report
+
+
+ timesheet.work
+ graph
+ work_graph
+
+
+
+ Works
+ timesheet.work
+
+
+
+
+
+
+
+
+
+
+
+
+ Open
+
+
+
+
+
+
+ All
+
+
+
+
+
+
+
+ Works
+ timesheet.work
+ timesheet.work.context
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ User in companies
+
+
+
+
+
+
+
+
+
+ timesheet.work.context
+ form
+ work_context_form
+
+
+
diff --git a/modules/timesheet_cost/.drone.yml b/modules/timesheet_cost/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/timesheet_cost/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/timesheet_cost/.flake8 b/modules/timesheet_cost/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/timesheet_cost/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/timesheet_cost/.isort.cfg b/modules/timesheet_cost/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/timesheet_cost/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/timesheet_cost/CHANGELOG b/modules/timesheet_cost/CHANGELOG
new file mode 100644
index 0000000000..573a2356b9
--- /dev/null
+++ b/modules/timesheet_cost/CHANGELOG
@@ -0,0 +1,63 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 2.7
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+
+Version 4.2.0 - 2016-11-28
+* Bug fixes (see mercurial logs for details)
+
+Version 4.0.0 - 2016-05-02
+* Bug fixes (see mercurial logs for details)
+* Add Python3 support
+
+Version 3.8.0 - 2015-11-02
+* Bug fixes (see mercurial logs for details)
+* Store cost price on timesheet line
+
+Version 3.6.0 - 2015-04-20
+* Bug fixes (see mercurial logs for details)
+* Add support for PyPy
+Version 3.4.0 - 2014-10-20
+* Bug fixes (see mercurial logs for details)
+
+Version 3.2.0 - 2014-04-21
+* Bug fixes (see mercurial logs for details)
+
+Version 3.0.0 - 2013-10-21
+* Initial release
diff --git a/modules/timesheet_cost/COPYRIGHT b/modules/timesheet_cost/COPYRIGHT
new file mode 100644
index 0000000000..d3964e68a4
--- /dev/null
+++ b/modules/timesheet_cost/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2008-2022 Cédric Krier.
+Copyright (C) 2008-2022 B2CK SPRL.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/timesheet_cost/LICENSE b/modules/timesheet_cost/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/timesheet_cost/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/timesheet_cost/MANIFEST.in b/modules/timesheet_cost/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/timesheet_cost/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/timesheet_cost/README.rst b/modules/timesheet_cost/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/timesheet_cost/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/timesheet_cost/__init__.py b/modules/timesheet_cost/__init__.py
new file mode 100644
index 0000000000..2a96cb3f43
--- /dev/null
+++ b/modules/timesheet_cost/__init__.py
@@ -0,0 +1,14 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import company, timesheet
+
+
+def register():
+ Pool.register(
+ company.Employee,
+ company.EmployeeCostPrice,
+ timesheet.Line,
+ module='timesheet_cost', type_='model')
diff --git a/modules/timesheet_cost/company.py b/modules/timesheet_cost/company.py
new file mode 100644
index 0000000000..bdaa306551
--- /dev/null
+++ b/modules/timesheet_cost/company.py
@@ -0,0 +1,126 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from decimal import Decimal
+
+from trytond.cache import Cache
+from trytond.config import config
+from trytond.model import Index, ModelSQL, ModelView, Unique, fields
+from trytond.pool import Pool, PoolMeta
+from trytond.transaction import Transaction
+
+__all__ = ['price_digits']
+
+price_digits = (16, config.getint(
+ 'timesheet_cost', 'price_decimal', default=4))
+
+
+class Employee(metaclass=PoolMeta):
+ __name__ = 'company.employee'
+ cost_price = fields.Function(fields.Numeric('Cost Price',
+ digits=price_digits,
+ help="Hourly cost price for this Employee."), 'get_cost_price')
+ cost_prices = fields.One2Many('company.employee_cost_price', 'employee',
+ 'Cost Prices', help="List of hourly cost price over time.")
+ _cost_prices_cache = Cache('company_employee.cost_prices')
+
+ def get_cost_price(self, name):
+ '''
+ Return the cost price at the date given in the context or the
+ current date
+ '''
+ ctx_date = Transaction().context.get('date', None)
+ return self.compute_cost_price(ctx_date)
+
+ def get_employee_costs(self):
+ "Return a sorted list by date of start date and cost_price"
+ pool = Pool()
+ CostPrice = pool.get('company.employee_cost_price')
+ # Get from cache employee costs or fetch them from the db
+ employee_costs = self._cost_prices_cache.get(self.id)
+ if employee_costs is None:
+ cost_prices = CostPrice.search([
+ ('employee', '=', self.id),
+ ], order=[('date', 'ASC')])
+
+ employee_costs = []
+ for cost_price in cost_prices:
+ employee_costs.append(
+ (cost_price.date, cost_price.cost_price))
+ self._cost_prices_cache.set(self.id, employee_costs)
+ return employee_costs
+
+ def compute_cost_price(self, date=None):
+ "Return the cost price at the given date"
+ pool = Pool()
+ Date = pool.get('ir.date')
+
+ employee_costs = self.get_employee_costs()
+
+ if date is None:
+ with Transaction().set_context(company=self.company.id):
+ date = Date.today()
+ # compute the cost price for the given date
+ cost = 0
+ if employee_costs and date >= employee_costs[0][0]:
+ for edate, ecost in employee_costs:
+ if date >= edate:
+ cost = ecost
+ else:
+ break
+ return cost
+
+
+class EmployeeCostPrice(ModelSQL, ModelView):
+ 'Employee Cost Price'
+ __name__ = 'company.employee_cost_price'
+ date = fields.Date("Date", required=True)
+ cost_price = fields.Numeric('Cost Price',
+ digits=price_digits, required=True, help="Hourly cost price.")
+ employee = fields.Many2One('company.employee', 'Employee')
+
+ @classmethod
+ def __setup__(cls):
+ super(EmployeeCostPrice, cls).__setup__()
+ t = cls.__table__()
+ cls._sql_constraints = [
+ ('employee_date_cost_price_uniq',
+ Unique(t, t.employee, t.date, t.cost_price),
+ 'timesheet_cost.msg_employee_unique_cost_price_date'),
+ ]
+ cls._sql_indexes.add(
+ Index(
+ t,
+ (t.employee, Index.Equality()),
+ (t.date, Index.Range(order='ASC'))))
+ cls._order.insert(0, ('date', 'DESC'))
+
+ @staticmethod
+ def default_cost_price():
+ return Decimal(0)
+
+ @staticmethod
+ def default_date():
+ Date = Pool().get('ir.date')
+ return Date.today()
+
+ def get_rec_name(self, name):
+ return str(self.date)
+
+ @classmethod
+ def delete(cls, prices):
+ Employee = Pool().get('company.employee')
+ super(EmployeeCostPrice, cls).delete(prices)
+ Employee._cost_prices_cache.clear()
+
+ @classmethod
+ def create(cls, vlist):
+ Employee = Pool().get('company.employee')
+ prices = super(EmployeeCostPrice, cls).create(vlist)
+ Employee._cost_prices_cache.clear()
+ return prices
+
+ @classmethod
+ def write(cls, *args):
+ Employee = Pool().get('company.employee')
+ super(EmployeeCostPrice, cls).write(*args)
+ Employee._cost_prices_cache.clear()
diff --git a/modules/timesheet_cost/company.xml b/modules/timesheet_cost/company.xml
new file mode 100644
index 0000000000..b0eb21e4e0
--- /dev/null
+++ b/modules/timesheet_cost/company.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+ company.employee_cost_price
+ form
+ employee_cost_price_form
+
+
+
+ company.employee_cost_price
+ tree
+ employee_cost_price_tree
+
+
+
+ company.employee
+
+ employee_form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/timesheet_cost/doc/index.rst b/modules/timesheet_cost/doc/index.rst
new file mode 100644
index 0000000000..2a19ea1326
--- /dev/null
+++ b/modules/timesheet_cost/doc/index.rst
@@ -0,0 +1,4 @@
+Timesheet Cost Module
+#####################
+
+The timesheet cost module adds cost price per employee.
diff --git a/modules/timesheet_cost/locale/bg.po b/modules/timesheet_cost/locale/bg.po
new file mode 100644
index 0000000000..75ca04e00c
--- /dev/null
+++ b/modules/timesheet_cost/locale/bg.po
@@ -0,0 +1,54 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Фабрична цена"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Себестойност"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Фабрична цена"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Дата"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Служител"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Фабрична цена"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Себестойност за час за този служител"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Списък на себестойност за час през времето"
+
+#, fuzzy
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Себестойност за час"
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Себестойност на клиент"
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr ""
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Разход"
diff --git a/modules/timesheet_cost/locale/ca.po b/modules/timesheet_cost/locale/ca.po
new file mode 100644
index 0000000000..1d781df650
--- /dev/null
+++ b/modules/timesheet_cost/locale/ca.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Preu de cost"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Preus de cost"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Preu de cost"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Empleat"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Preu de cost"
+
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Preu de cost per hora per a aquest empleat."
+
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Llista de preus de cost per hora a través del temps."
+
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Preu de cost per hora."
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Preu de cost de l'empleat"
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr "Un empleat només pot tenir un preu de cost per data."
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Cost"
diff --git a/modules/timesheet_cost/locale/cs.po b/modules/timesheet_cost/locale/cs.po
new file mode 100644
index 0000000000..4116d879a5
--- /dev/null
+++ b/modules/timesheet_cost/locale/cs.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr ""
+
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr ""
+
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr ""
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr ""
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr ""
diff --git a/modules/timesheet_cost/locale/de.po b/modules/timesheet_cost/locale/de.po
new file mode 100644
index 0000000000..cea043fb7e
--- /dev/null
+++ b/modules/timesheet_cost/locale/de.po
@@ -0,0 +1,53 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Einstandspreis"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Einstandspreise"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Einstandspreis"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Datum"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Mitarbeiter"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Einstandspreis"
+
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Einstandspreis pro Stunde für diesen Mitarbeiter."
+
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Entwicklung des Einstandspreises pro Stunde."
+
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Einstandspreis pro Stunde."
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Mitarbeiter Einstandspreis"
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr ""
+"Es kann nur ein Einstandspreis pro Datum für einen Mitarbeiter eingetragen "
+"werden."
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Kosten"
diff --git a/modules/timesheet_cost/locale/es.po b/modules/timesheet_cost/locale/es.po
new file mode 100644
index 0000000000..53d87f783e
--- /dev/null
+++ b/modules/timesheet_cost/locale/es.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Precio de coste"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Precios de coste"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Precio de coste"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Fecha"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Empleado"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Precio de coste"
+
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Precio de coste por hora para este empleado."
+
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Lista de precios de coste por hora a lo largo del tiempo."
+
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Precio de coste por hora."
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Precio de coste del empleado"
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr "Un empleado sólo puede tener un precio de coste por fecha."
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Coste"
diff --git a/modules/timesheet_cost/locale/es_419.po b/modules/timesheet_cost/locale/es_419.po
new file mode 100644
index 0000000000..99398c4171
--- /dev/null
+++ b/modules/timesheet_cost/locale/es_419.po
@@ -0,0 +1,54 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Precio de costo"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Precios de costo"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Precio de costo"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Precio de costo"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Precio de costo por hora para este empleado"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Lista de precio de costo por hora de tiempo extra"
+
+#, fuzzy
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Precio de costo por hora"
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Precio de costo del empleado"
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr ""
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Costo"
diff --git a/modules/timesheet_cost/locale/et.po b/modules/timesheet_cost/locale/et.po
new file mode 100644
index 0000000000..9b138fc9e0
--- /dev/null
+++ b/modules/timesheet_cost/locale/et.po
@@ -0,0 +1,54 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Ostuhind"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Ostuhinnad"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Ostuhind"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Kuupäev"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Töötaja"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Ostuhind"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Töötaja tunnitasu"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Tunnitasu ületunni hind"
+
+#, fuzzy
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Tunnitasu"
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Töötaja tasu"
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr "Töötajal saab olla ainult üks tasu kuupäeva kohta"
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Kulu"
diff --git a/modules/timesheet_cost/locale/fa.po b/modules/timesheet_cost/locale/fa.po
new file mode 100644
index 0000000000..bddcb19466
--- /dev/null
+++ b/modules/timesheet_cost/locale/fa.po
@@ -0,0 +1,54 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "مبلغ هزینه"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "مبالغ هزینه"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "مبلغ هزینه"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "تاریخ"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "کارمند"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "مبلغ هزینه"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "مبلغ هزینه ساعتی برای این کارمند"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "لیست مبلغ هزینه ساعتی اضافه کار"
+
+#, fuzzy
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "مبلغ هزینه ساعتی"
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "مبلغ هزینه کارمند"
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr "در هر تاریخ ،یک کارمند تنها می تواند یک مبلغ هزینه داشته باشد."
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "هزینه"
diff --git a/modules/timesheet_cost/locale/fi.po b/modules/timesheet_cost/locale/fi.po
new file mode 100644
index 0000000000..4116d879a5
--- /dev/null
+++ b/modules/timesheet_cost/locale/fi.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr ""
+
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr ""
+
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr ""
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr ""
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr ""
diff --git a/modules/timesheet_cost/locale/fr.po b/modules/timesheet_cost/locale/fr.po
new file mode 100644
index 0000000000..e7e63d7601
--- /dev/null
+++ b/modules/timesheet_cost/locale/fr.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Prix de revient"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Prix de revient"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Prix de revient"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Date"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Employé"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Prix de revient"
+
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Prix de revient horaire de cet employé."
+
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Liste du prix de revient horaire au cours du temps."
+
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Prix de revient horaire."
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Prix de revient de l'employé"
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr "Un employé ne peut avoir qu'un seul prix de revient par date."
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Coût"
diff --git a/modules/timesheet_cost/locale/hu.po b/modules/timesheet_cost/locale/hu.po
new file mode 100644
index 0000000000..a92064e1a6
--- /dev/null
+++ b/modules/timesheet_cost/locale/hu.po
@@ -0,0 +1,55 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Költség"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Költség"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Költség"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Dátum"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Alkalmazott"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Költség"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Alkalmazott költsége per óra "
+
+#, fuzzy
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Lista a költség per óráról"
+
+#, fuzzy
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Költség per óra"
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Alkalmazott költsége"
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr "Egy alkalmazottnak dátumonként egy költség írható be."
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Költség"
diff --git a/modules/timesheet_cost/locale/id.po b/modules/timesheet_cost/locale/id.po
new file mode 100644
index 0000000000..e031863541
--- /dev/null
+++ b/modules/timesheet_cost/locale/id.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Tanggal"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Karyawan"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr ""
+
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr ""
+
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr ""
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr ""
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr ""
diff --git a/modules/timesheet_cost/locale/it.po b/modules/timesheet_cost/locale/it.po
new file mode 100644
index 0000000000..d9b4a41b0a
--- /dev/null
+++ b/modules/timesheet_cost/locale/it.po
@@ -0,0 +1,52 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Prezzo di costo"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Costi"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Prezzo di costo"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Dipendente"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Prezzo di costo"
+
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Costo orario per questo dipendente."
+
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Elenco dei costi orari nel tempo."
+
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Prezzo di costo orario."
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Costo del dipendente"
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr "Un dipendente può avere un costo giornaliero."
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Costo"
diff --git a/modules/timesheet_cost/locale/lo.po b/modules/timesheet_cost/locale/lo.po
new file mode 100644
index 0000000000..fea5eea26c
--- /dev/null
+++ b/modules/timesheet_cost/locale/lo.po
@@ -0,0 +1,55 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "ລາຄາຄິດໄລ່"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "ລາຄາຄິດໄລ່"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "ລາຄາຄິດໄລ່"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "ວັນທີ"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "ພະນັກງານ"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "ລາຄາຄິດໄລ່"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "ລາຄາຕໍ່ຊົ່ວໂມງສຳລັບພະນັກງານຜູ້ນີ້"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "ບັນຊີລາຍການຄ່າລ່ວງເວລາ"
+
+#, fuzzy
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "ລາຄາຕໍ່ຊົ່ວໂມງ"
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "ມູນຄ່າລາຄາພະນັກງານ"
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr "ລູກຈ້າງຜູ້ໜຶ່ງສາມາດມີພຽງມູນຄ່າລາຄາດຽວຕໍ່ມື້ເທົ່ານັ້ນ"
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "ມູນຄ່າ"
diff --git a/modules/timesheet_cost/locale/lt.po b/modules/timesheet_cost/locale/lt.po
new file mode 100644
index 0000000000..4116d879a5
--- /dev/null
+++ b/modules/timesheet_cost/locale/lt.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr ""
+
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr ""
+
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr ""
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr ""
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr ""
diff --git a/modules/timesheet_cost/locale/nl.po b/modules/timesheet_cost/locale/nl.po
new file mode 100644
index 0000000000..2a07b25181
--- /dev/null
+++ b/modules/timesheet_cost/locale/nl.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Kostprijs"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Kostprijzen"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Kostprijs"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Datum"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Werknemer"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Kostprijs"
+
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Kostprijs per uur voor deze werknemer."
+
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Lijst met kostprijs per uur in de tijd."
+
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Kostprijs per uur."
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Werknemer kostprijs"
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr "Een medewerker kan slechts één kostprijs hebben per datum."
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Kosten"
diff --git a/modules/timesheet_cost/locale/pl.po b/modules/timesheet_cost/locale/pl.po
new file mode 100644
index 0000000000..f76a7c0096
--- /dev/null
+++ b/modules/timesheet_cost/locale/pl.po
@@ -0,0 +1,54 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Cena kosztów"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Ceny kosztów"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Cena kosztów"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Pracownik"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Cena kosztów"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Godzinowa cena kosztów"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Godzinowa cena kosztów"
+
+#, fuzzy
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Godzinowa cena kosztów"
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Robocza cena kosztów"
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr ""
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Koszt"
diff --git a/modules/timesheet_cost/locale/pt.po b/modules/timesheet_cost/locale/pt.po
new file mode 100644
index 0000000000..409eaad639
--- /dev/null
+++ b/modules/timesheet_cost/locale/pt.po
@@ -0,0 +1,55 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Preço de custo"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Preços de custo"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Preços de custo"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Empregado"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Preço de custo"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Preço de custo por hora para este empregado."
+
+#, fuzzy
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Lista de preços de custo por hora ao longo do tempo."
+
+#, fuzzy
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Preço de custo por hora"
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Preço de custo do empregado"
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr "Um empregado somente pode ter um preço de custo por data."
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Custo"
diff --git a/modules/timesheet_cost/locale/ro.po b/modules/timesheet_cost/locale/ro.po
new file mode 100644
index 0000000000..b6d418bca7
--- /dev/null
+++ b/modules/timesheet_cost/locale/ro.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Cost"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Costuri"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Cost"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Data"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Angajat"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Cost"
+
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Costul orar pentru acest Angajat."
+
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Lista de cost pe ora în timp."
+
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Preț de cost orar."
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Preţ de cost Angajat"
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr "Un angajat poate avea numai un sigur cost pe data."
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Cost"
diff --git a/modules/timesheet_cost/locale/ru.po b/modules/timesheet_cost/locale/ru.po
new file mode 100644
index 0000000000..21f6baf388
--- /dev/null
+++ b/modules/timesheet_cost/locale/ru.po
@@ -0,0 +1,55 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Себестоимость"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Себестоимость"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Себестоимость"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Дата"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Сотрудник"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Себестоимость"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Часовая себестоимость для этого сотрудника"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Список часовой себестоимости по времени"
+
+#, fuzzy
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Часовая себестоимость"
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Себестоимость сотрудника"
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr "У сотрудника может быть только одна себестоимость за день."
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Стоимость"
diff --git a/modules/timesheet_cost/locale/sl.po b/modules/timesheet_cost/locale/sl.po
new file mode 100644
index 0000000000..d502e0fdc0
--- /dev/null
+++ b/modules/timesheet_cost/locale/sl.po
@@ -0,0 +1,55 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Strošek"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Stroški"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Strošek"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Datum"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Zaposlenec"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Strošek"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Strošek na uro za tega zaposlenca"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Seznam stroškov na uro po času"
+
+#, fuzzy
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Strošek na uro"
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Strošek zaposlenca"
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr "Zaposlenec ima lahko samo en strošek na datum."
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Strošek"
diff --git a/modules/timesheet_cost/locale/tr.po b/modules/timesheet_cost/locale/tr.po
new file mode 100644
index 0000000000..ec155b1ca6
--- /dev/null
+++ b/modules/timesheet_cost/locale/tr.po
@@ -0,0 +1,55 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr "Maliyet Fiyatı"
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr "Maliyet Fiyatları"
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr "Maliyet Fiyatı"
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "Tarih"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr "Çalışan"
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr "Maliyet fiyatı"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr "Bu çalışan için saatlik maliyet fiyatı"
+
+#, fuzzy
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr "Saatlik fazla mesai maliyet fiyatı listesi"
+
+#, fuzzy
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr "Saatlik maliyet fiyatı"
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr "Çalışan Maliyet Fiyatı"
+
+#, fuzzy
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr "Bir çalışan için tarihe göre yalnız bir maliyet fiyatı olabilir"
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr "Maliyet"
diff --git a/modules/timesheet_cost/locale/uk.po b/modules/timesheet_cost/locale/uk.po
new file mode 100644
index 0000000000..4116d879a5
--- /dev/null
+++ b/modules/timesheet_cost/locale/uk.po
@@ -0,0 +1,51 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr ""
+
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr ""
+
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr ""
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr ""
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr ""
diff --git a/modules/timesheet_cost/locale/zh_CN.po b/modules/timesheet_cost/locale/zh_CN.po
new file mode 100644
index 0000000000..b07fba4c2e
--- /dev/null
+++ b/modules/timesheet_cost/locale/zh_CN.po
@@ -0,0 +1,52 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:company.employee,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "field:company.employee,cost_prices:"
+msgid "Cost Prices"
+msgstr ""
+
+msgctxt "field:company.employee_cost_price,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+#, fuzzy
+msgctxt "field:company.employee_cost_price,date:"
+msgid "Date"
+msgstr "日期格式"
+
+msgctxt "field:company.employee_cost_price,employee:"
+msgid "Employee"
+msgstr ""
+
+msgctxt "field:timesheet.line,cost_price:"
+msgid "Cost Price"
+msgstr ""
+
+msgctxt "help:company.employee,cost_price:"
+msgid "Hourly cost price for this Employee."
+msgstr ""
+
+msgctxt "help:company.employee,cost_prices:"
+msgid "List of hourly cost price over time."
+msgstr ""
+
+msgctxt "help:company.employee_cost_price,cost_price:"
+msgid "Hourly cost price."
+msgstr ""
+
+msgctxt "model:company.employee_cost_price,name:"
+msgid "Employee Cost Price"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_employee_unique_cost_price_date"
+msgid "An employee can only have one cost price by date."
+msgstr ""
+
+msgctxt "view:company.employee:"
+msgid "Cost"
+msgstr ""
diff --git a/modules/timesheet_cost/message.xml b/modules/timesheet_cost/message.xml
new file mode 100644
index 0000000000..ce99310cbe
--- /dev/null
+++ b/modules/timesheet_cost/message.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+ An employee can only have one cost price by date.
+
+
+
diff --git a/modules/timesheet_cost/setup.py b/modules/timesheet_cost/setup.py
new file mode 100755
index 0000000000..96981c1b74
--- /dev/null
+++ b/modules/timesheet_cost/setup.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_timesheet_cost'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = ['python-sql >= 0.4']
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module to add cost on timesheet',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/timesheet_cost',
+ },
+ keywords='tryton timesheet cost',
+ package_dir={'trytond.modules.timesheet_cost': '.'},
+ packages=(
+ ['trytond.modules.timesheet_cost']
+ + ['trytond.modules.timesheet_cost.%s' % p for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.timesheet_cost': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'Intended Audience :: Manufacturing',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ timesheet_cost = trytond.modules.timesheet_cost
+ """,
+ )
diff --git a/modules/timesheet_cost/tests/__init__.py b/modules/timesheet_cost/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/timesheet_cost/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/timesheet_cost/tests/test_module.py b/modules/timesheet_cost/tests/test_module.py
new file mode 100644
index 0000000000..47dbfa19e3
--- /dev/null
+++ b/modules/timesheet_cost/tests/test_module.py
@@ -0,0 +1,52 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import datetime
+from decimal import Decimal
+
+from trytond.modules.company.tests import (
+ CompanyTestMixin, create_company, create_employee, set_company)
+from trytond.pool import Pool
+from trytond.tests.test_tryton import ModuleTestCase, with_transaction
+
+
+class TimesheetCostTestCase(CompanyTestMixin, ModuleTestCase):
+ 'Test TimesheetCost module'
+ module = 'timesheet_cost'
+
+ @with_transaction()
+ def test_compute_cost_price(self):
+ 'Test compute_cost_price'
+ pool = Pool()
+ Party = pool.get('party.party')
+ EmployeeCostPrice = pool.get('company.employee_cost_price')
+
+ cost_prices = [
+ (datetime.date(2011, 1, 1), Decimal(10)),
+ (datetime.date(2012, 1, 1), Decimal(15)),
+ (datetime.date(2013, 1, 1), Decimal(20)),
+ ]
+ test_prices = [
+ (datetime.date(2010, 1, 1), 0),
+ (datetime.date(2011, 1, 1), Decimal(10)),
+ (datetime.date(2011, 6, 1), Decimal(10)),
+ (datetime.date(2012, 1, 1), Decimal(15)),
+ (datetime.date(2012, 6, 1), Decimal(15)),
+ (datetime.date(2013, 1, 1), Decimal(20)),
+ (datetime.date(2013, 6, 1), Decimal(20)),
+ ]
+ party = Party(name='Pam Beesly')
+ party.save()
+ company = create_company()
+ with set_company(company):
+ employee = create_employee(company)
+ for date, cost_price in cost_prices:
+ EmployeeCostPrice(
+ employee=employee,
+ date=date,
+ cost_price=cost_price).save()
+ for date, cost_price in test_prices:
+ self.assertEqual(employee.compute_cost_price(date), cost_price)
+
+
+del ModuleTestCase
diff --git a/modules/timesheet_cost/timesheet.py b/modules/timesheet_cost/timesheet.py
new file mode 100644
index 0000000000..9a2ebdcb1f
--- /dev/null
+++ b/modules/timesheet_cost/timesheet.py
@@ -0,0 +1,77 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from sql import Null
+
+from trytond.model import fields
+from trytond.pool import Pool, PoolMeta
+from trytond.transaction import Transaction
+
+from .company import price_digits
+
+
+class Line(metaclass=PoolMeta):
+ __name__ = 'timesheet.line'
+
+ cost_price = fields.Numeric('Cost Price',
+ digits=price_digits, required=True, readonly=True)
+
+ @classmethod
+ def __register__(cls, module_name):
+ pool = Pool()
+ Employee = pool.get('company.employee')
+
+ transaction = Transaction()
+ cursor = transaction.connection.cursor()
+ update = transaction.connection.cursor()
+ table = cls.__table__()
+ table_h = cls.__table_handler__(module_name)
+
+ migrate_cost_price = not table_h.column_exist('cost_price')
+
+ super().__register__(module_name)
+
+ # Migration from 3.6: add cost_price
+ if migrate_cost_price:
+ cursor.execute(*table.select(table.id, table.employee, table.date,
+ where=(table.cost_price == 0)
+ & (table.employee != Null)
+ & (table.date != Null)))
+ for line_id, employee_id, date in cursor:
+ employee = Employee(employee_id)
+ cost_price = employee.compute_cost_price(date=date)
+ update.execute(*table.update(
+ [table.cost_price],
+ [cost_price],
+ where=table.id == line_id))
+
+ @classmethod
+ def default_cost_price(cls):
+ # Needed at creation as cost_price is required
+ return 0
+
+ @classmethod
+ def create(cls, vlist):
+ # XXX Remove cost_price because proteus set it as default value
+ vlist = [v.copy() for v in vlist]
+ for values in vlist:
+ values.pop('cost_price', None)
+ lines = super().create(vlist)
+ cls.sync_cost(lines)
+ return lines
+
+ @classmethod
+ def write(cls, *args):
+ super().write(*args)
+ cls.sync_cost(sum(args[0:None:2], []))
+
+ @classmethod
+ def sync_cost(cls, lines):
+ with Transaction().set_context(_check_access=False):
+ to_write = []
+ lines = cls.browse(lines)
+ for line in lines:
+ cost_price = line.employee.compute_cost_price(date=line.date)
+ if cost_price != line.cost_price:
+ to_write.extend([[line], {'cost_price': cost_price}])
+ if to_write:
+ cls.write(*to_write)
diff --git a/modules/timesheet_cost/timesheet.xml b/modules/timesheet_cost/timesheet.xml
new file mode 100644
index 0000000000..c8b33c898c
--- /dev/null
+++ b/modules/timesheet_cost/timesheet.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/timesheet_cost/tox.ini b/modules/timesheet_cost/tox.ini
new file mode 100644
index 0000000000..b5615a3b3d
--- /dev/null
+++ b/modules/timesheet_cost/tox.ini
@@ -0,0 +1,16 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+commands =
+ coverage run --include=./**/timesheet_cost/* -m unittest discover -s tests
+ coverage report --include=./**/timesheet_cost/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/timesheet_cost/tryton.cfg b/modules/timesheet_cost/tryton.cfg
new file mode 100644
index 0000000000..e408be2a79
--- /dev/null
+++ b/modules/timesheet_cost/tryton.cfg
@@ -0,0 +1,11 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ company
+ party
+ timesheet
+xml:
+ company.xml
+ timesheet.xml
+ message.xml
diff --git a/modules/timesheet_cost/view/employee_cost_price_form.xml b/modules/timesheet_cost/view/employee_cost_price_form.xml
new file mode 100644
index 0000000000..c1eaedc73b
--- /dev/null
+++ b/modules/timesheet_cost/view/employee_cost_price_form.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/modules/timesheet_cost/view/employee_cost_price_tree.xml b/modules/timesheet_cost/view/employee_cost_price_tree.xml
new file mode 100644
index 0000000000..0cd0e159a0
--- /dev/null
+++ b/modules/timesheet_cost/view/employee_cost_price_tree.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
diff --git a/modules/timesheet_cost/view/employee_form.xml b/modules/timesheet_cost/view/employee_form.xml
new file mode 100644
index 0000000000..ca069d26ff
--- /dev/null
+++ b/modules/timesheet_cost/view/employee_form.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/user_role/.drone.yml b/modules/user_role/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/user_role/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/user_role/.flake8 b/modules/user_role/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/user_role/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/user_role/.isort.cfg b/modules/user_role/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/user_role/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/user_role/CHANGELOG b/modules/user_role/CHANGELOG
new file mode 100644
index 0000000000..64b819e360
--- /dev/null
+++ b/modules/user_role/CHANGELOG
@@ -0,0 +1,28 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Use datetime for role planning
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Remove support for Python 3.5
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 5.2.0 - 2019-05-06
+* Initial release
diff --git a/modules/user_role/COPYRIGHT b/modules/user_role/COPYRIGHT
new file mode 100644
index 0000000000..e7297d1171
--- /dev/null
+++ b/modules/user_role/COPYRIGHT
@@ -0,0 +1,14 @@
+Copyright (C) 2018-2022 Cédric Krier
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/user_role/LICENSE b/modules/user_role/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/user_role/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/user_role/MANIFEST.in b/modules/user_role/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/user_role/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/user_role/README.rst b/modules/user_role/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/user_role/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/user_role/__init__.py b/modules/user_role/__init__.py
new file mode 100644
index 0000000000..742290f2a1
--- /dev/null
+++ b/modules/user_role/__init__.py
@@ -0,0 +1,22 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import ir, res
+
+__all__ = ['register']
+
+
+def register():
+ Pool.register(
+ res.Role,
+ res.RoleGroup,
+ res.User,
+ res.UserRole,
+ ir.Cron,
+ module='user_role', type_='model')
+ Pool.register(
+ module='user_role', type_='wizard')
+ Pool.register(
+ module='user_role', type_='report')
diff --git a/modules/user_role/doc/index.rst b/modules/user_role/doc/index.rst
new file mode 100644
index 0000000000..17f9e219f1
--- /dev/null
+++ b/modules/user_role/doc/index.rst
@@ -0,0 +1,6 @@
+User Role Module
+################
+
+The user_role module allows to assign roles to user instead of groups.
+A *Role* is defined by a set of groups. When a role is added to a user, it
+overrides the existing groups. A role can be added to a user for a period.
diff --git a/modules/user_role/ir.py b/modules/user_role/ir.py
new file mode 100644
index 0000000000..e9897f816a
--- /dev/null
+++ b/modules/user_role/ir.py
@@ -0,0 +1,13 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.pool import PoolMeta
+
+
+class Cron(metaclass=PoolMeta):
+ __name__ = 'ir.cron'
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls.method.selection.append(
+ ('res.user|sync_roles', "Synchronize Users Roles"))
diff --git a/modules/user_role/locale/bg.po b/modules/user_role/locale/bg.po
new file mode 100644
index 0000000000..e0b2cb7442
--- /dev/null
+++ b/modules/user_role/locale/bg.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr ""
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr ""
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr ""
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr ""
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr ""
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr ""
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/ca.po b/modules/user_role/locale/ca.po
new file mode 100644
index 0000000000..4494b1e0d5
--- /dev/null
+++ b/modules/user_role/locale/ca.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr "Grups"
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr "Nom"
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr "Grup"
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr "Rol"
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr "Rols"
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr "Des de la data"
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr "Rol"
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr "Fins a la data"
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr "Usuari"
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr "Rols"
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr "Rols"
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr "Rol"
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr "Rol - Grup"
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr "Rol d'usuari"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr "Sincronitza rols d'usuari"
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr "Hora"
diff --git a/modules/user_role/locale/cs.po b/modules/user_role/locale/cs.po
new file mode 100644
index 0000000000..e0b2cb7442
--- /dev/null
+++ b/modules/user_role/locale/cs.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr ""
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr ""
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr ""
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr ""
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr ""
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr ""
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/de.po b/modules/user_role/locale/de.po
new file mode 100644
index 0000000000..e21aa723af
--- /dev/null
+++ b/modules/user_role/locale/de.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr "Gruppen"
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr "Name"
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr "Gruppe"
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr "Rolle"
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr "Rollen"
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr "Von Datum"
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr "Rolle"
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr "Bis Datum"
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr "Benutzer"
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr "Rollen"
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr "Rollen"
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr "Rolle"
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr "Rolle - Gruppe"
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr "Benutzerrolle"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr "Benutzerrollen synchronisieren"
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr "Uhrzeit"
diff --git a/modules/user_role/locale/es.po b/modules/user_role/locale/es.po
new file mode 100644
index 0000000000..0f063305af
--- /dev/null
+++ b/modules/user_role/locale/es.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr "Grupos"
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr "Nombre"
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr "Grupo"
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr "Rol"
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr "Roles"
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr "Desde la fecha"
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr "Rol"
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr "Hasta la fecha"
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr "Usuario"
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr "Roles"
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr "Roles"
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr "Rol"
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr "Rol - Grupo"
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr "Rol de usuario"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr "Sincronizar roles de usuario"
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr "Hora"
diff --git a/modules/user_role/locale/es_419.po b/modules/user_role/locale/es_419.po
new file mode 100644
index 0000000000..e0b2cb7442
--- /dev/null
+++ b/modules/user_role/locale/es_419.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr ""
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr ""
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr ""
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr ""
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr ""
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr ""
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/et.po b/modules/user_role/locale/et.po
new file mode 100644
index 0000000000..745b67febc
--- /dev/null
+++ b/modules/user_role/locale/et.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr "Grupid"
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr "Nimi"
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr "Grupp"
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr "Roll"
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr "Rollid"
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr "Kuupäevast"
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr "Roll"
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr "Kuupäevani"
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr "Kasutaja"
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr "Rollid"
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr "Rollid"
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr "Roll"
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr "Roll - Grupp"
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr "Kasutajaroll"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr "Sünkroniseeri kasutajarollid"
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/fa.po b/modules/user_role/locale/fa.po
new file mode 100644
index 0000000000..e2df5a06ac
--- /dev/null
+++ b/modules/user_role/locale/fa.po
@@ -0,0 +1,68 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr "گروه ها"
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr "نام"
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr "گروه"
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr "نقش، وظیفه"
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr "نقش ها، وظایف"
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr "از تاریخ"
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr "نقش، وظیفه"
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr "تا تاریخ"
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr "کاربر"
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr "نقش ها، وظایف"
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr "نقش ها، وظایف"
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr "نقش، وظیفه"
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr "گروه - نقش، وظیفه"
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr "نقش کاربر"
+
+#, fuzzy
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr "هماهنگ سازی نقش های کاربران"
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/fi.po b/modules/user_role/locale/fi.po
new file mode 100644
index 0000000000..e0b2cb7442
--- /dev/null
+++ b/modules/user_role/locale/fi.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr ""
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr ""
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr ""
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr ""
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr ""
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr ""
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/fr.po b/modules/user_role/locale/fr.po
new file mode 100644
index 0000000000..27374085b9
--- /dev/null
+++ b/modules/user_role/locale/fr.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr "Groupes"
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr "Nom"
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr "Groupe"
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr "Rôle"
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr "Rôles"
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr "Date de début"
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr "Rôle"
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr "Date de fin"
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr "Utilisateur"
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr "Rôles"
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr "Rôles"
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr "Rôle"
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr "Rôle - Groupe"
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr "Rôle utilisateur"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr "Synchroniser les utilisateurs et rôles"
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr "Heure"
diff --git a/modules/user_role/locale/hu.po b/modules/user_role/locale/hu.po
new file mode 100644
index 0000000000..e0b2cb7442
--- /dev/null
+++ b/modules/user_role/locale/hu.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr ""
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr ""
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr ""
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr ""
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr ""
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr ""
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/id.po b/modules/user_role/locale/id.po
new file mode 100644
index 0000000000..ef79cc288c
--- /dev/null
+++ b/modules/user_role/locale/id.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr ""
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr "Nama"
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr "Kelompok"
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr ""
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr "Dari Tanggal"
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr "Ke Tanggal"
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr "Pengguna"
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr ""
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr ""
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr ""
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/it.po b/modules/user_role/locale/it.po
new file mode 100644
index 0000000000..36fc813b04
--- /dev/null
+++ b/modules/user_role/locale/it.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr "Gruppi"
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr "Nome"
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr "Gruppo"
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr "Ruolo"
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr "Ruoli"
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr "Dalla data"
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr "Ruolo"
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr "A data"
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr "Utente"
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr "Ruoli"
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr "Ruoli"
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr "Ruolo"
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr "Ruolo - Gruppo"
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr "Ruolo utente"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr "Sincronizza ruoli utenti"
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr "Orario"
diff --git a/modules/user_role/locale/lo.po b/modules/user_role/locale/lo.po
new file mode 100644
index 0000000000..e0b2cb7442
--- /dev/null
+++ b/modules/user_role/locale/lo.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr ""
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr ""
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr ""
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr ""
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr ""
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr ""
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/lt.po b/modules/user_role/locale/lt.po
new file mode 100644
index 0000000000..444be4de29
--- /dev/null
+++ b/modules/user_role/locale/lt.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr ""
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr ""
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr ""
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr "Naudotojas"
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr ""
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr ""
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr "Naudotojo vaidmenys"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr ""
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/nl.po b/modules/user_role/locale/nl.po
new file mode 100644
index 0000000000..52fa2cf07f
--- /dev/null
+++ b/modules/user_role/locale/nl.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr "Groepen"
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr "Naam"
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr "Groep"
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr "Rol"
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr "Rollen"
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr "Vanaf datum"
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr "Rol"
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr "Einddatum"
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr "Gebruiker"
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr "Rollen"
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr "Rollen"
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr "Rol"
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr "Rol - groep"
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr "Gebruikersrol"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr "Gebruikersrollen synchroniseren"
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr "Tijd"
diff --git a/modules/user_role/locale/pl.po b/modules/user_role/locale/pl.po
new file mode 100644
index 0000000000..7e8cea099d
--- /dev/null
+++ b/modules/user_role/locale/pl.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr "Grupy"
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr "Nazwa"
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr "Grupa"
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr "Rola"
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr "Role"
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr "Od"
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr "Rola"
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr "Do"
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr "Użytkownik"
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr "Role"
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr "Role"
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr "Rola"
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr "Rola - Grupa"
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr "Rola użytkownika"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr "Synchronizuj role użytkowników"
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/pt.po b/modules/user_role/locale/pt.po
new file mode 100644
index 0000000000..e0b2cb7442
--- /dev/null
+++ b/modules/user_role/locale/pt.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr ""
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr ""
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr ""
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr ""
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr ""
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr ""
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/ro.po b/modules/user_role/locale/ro.po
new file mode 100644
index 0000000000..d01742d383
--- /dev/null
+++ b/modules/user_role/locale/ro.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr "Grupuri"
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr ""
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr ""
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr ""
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr ""
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr ""
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/ru.po b/modules/user_role/locale/ru.po
new file mode 100644
index 0000000000..e0b2cb7442
--- /dev/null
+++ b/modules/user_role/locale/ru.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr ""
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr ""
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr ""
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr ""
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr ""
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr ""
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/sl.po b/modules/user_role/locale/sl.po
new file mode 100644
index 0000000000..e0b2cb7442
--- /dev/null
+++ b/modules/user_role/locale/sl.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr ""
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr ""
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr ""
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr ""
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr ""
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr ""
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/tr.po b/modules/user_role/locale/tr.po
new file mode 100644
index 0000000000..e0b2cb7442
--- /dev/null
+++ b/modules/user_role/locale/tr.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr ""
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr ""
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr ""
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr ""
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr ""
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr ""
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/uk.po b/modules/user_role/locale/uk.po
new file mode 100644
index 0000000000..e0b2cb7442
--- /dev/null
+++ b/modules/user_role/locale/uk.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr ""
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr ""
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr ""
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr ""
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr ""
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr ""
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr ""
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr ""
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr ""
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr ""
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr ""
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr ""
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/locale/zh_CN.po b/modules/user_role/locale/zh_CN.po
new file mode 100644
index 0000000000..48ba9f5881
--- /dev/null
+++ b/modules/user_role/locale/zh_CN.po
@@ -0,0 +1,67 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:res.role,groups:"
+msgid "Groups"
+msgstr "组"
+
+msgctxt "field:res.role,name:"
+msgid "Name"
+msgstr "名称"
+
+msgctxt "field:res.role-res.group,group:"
+msgid "Group"
+msgstr "组"
+
+msgctxt "field:res.role-res.group,role:"
+msgid "Role"
+msgstr "角色"
+
+msgctxt "field:res.user,roles:"
+msgid "Roles"
+msgstr "角色"
+
+msgctxt "field:res.user.role,from_date:"
+msgid "From Date"
+msgstr "从日期"
+
+msgctxt "field:res.user.role,role:"
+msgid "Role"
+msgstr "角色"
+
+msgctxt "field:res.user.role,to_date:"
+msgid "To Date"
+msgstr "到日期"
+
+msgctxt "field:res.user.role,user:"
+msgid "User"
+msgstr "用户"
+
+msgctxt "model:ir.action,name:act_role_form"
+msgid "Roles"
+msgstr "角色"
+
+msgctxt "model:ir.ui.menu,name:menu_role_form"
+msgid "Roles"
+msgstr "角色"
+
+msgctxt "model:res.role,name:"
+msgid "Role"
+msgstr "角色"
+
+msgctxt "model:res.role-res.group,name:"
+msgid "Role - Group"
+msgstr "角色-组"
+
+msgctxt "model:res.user.role,name:"
+msgid "User Role"
+msgstr "用户角色"
+
+msgctxt "selection:ir.cron,method:"
+msgid "Synchronize Users Roles"
+msgstr "同步用户角色"
+
+msgctxt "view:res.user.role:"
+msgid "Time"
+msgstr ""
diff --git a/modules/user_role/res.py b/modules/user_role/res.py
new file mode 100644
index 0000000000..dfe1ecfb15
--- /dev/null
+++ b/modules/user_role/res.py
@@ -0,0 +1,117 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import datetime as dt
+
+from trytond.model import ModelSQL, ModelView, fields
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Bool, Eval, If
+
+
+class Role(ModelSQL, ModelView):
+ "Role"
+ __name__ = 'res.role'
+ name = fields.Char("Name", required=True, translate=True)
+ groups = fields.Many2Many('res.role-res.group', 'role', 'group', "Groups")
+
+ @classmethod
+ def write(cls, *args):
+ pool = Pool()
+ User = pool.get('res.user')
+ roles = sum(args[0:None:2], [])
+ super().write(*args)
+
+ users = User.search([
+ ('roles.role', 'in', [r.id for r in roles]),
+ ])
+ User.sync_roles(users)
+
+
+class RoleGroup(ModelSQL):
+ "Role - Group"
+ __name__ = 'res.role-res.group'
+ role = fields.Many2One(
+ 'res.role', "Role", ondelete='CASCADE', required=True)
+ group = fields.Many2One(
+ 'res.group', "Group", ondelete='CASCADE', required=True)
+
+
+class User(metaclass=PoolMeta):
+ __name__ = 'res.user'
+ roles = fields.One2Many('res.user.role', 'user', "Roles")
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ group_readonly = Bool(Eval('roles', []))
+ if 'readonly' in cls.groups.states:
+ group_readonly |= cls.groups.states['readonly']
+ cls.groups.states['readonly'] = group_readonly
+
+ cls._context_fields.append('roles')
+
+ @classmethod
+ def create(cls, vlist):
+ users = super().create(vlist)
+ cls.sync_roles(users)
+ return users
+
+ @classmethod
+ def write(cls, *args):
+ users = sum(args[0:None:2], [])
+ super().write(*args)
+ cls.sync_roles(users)
+
+ @classmethod
+ def sync_roles(cls, users=None, date=None):
+ if date is None:
+ date = dt.datetime.now()
+ if users is None:
+ users = cls.search([])
+ to_write = []
+ for user in users:
+ if not user.roles:
+ continue
+ new = {g.id for r in user.roles for g in r.role.groups
+ if r.valid(date)}
+ old = {g.id for g in user.groups}
+ if new != old:
+ to_write.append([user])
+ to_write.append({'groups': [
+ ('add', new - old),
+ ('remove', old - new),
+ ]})
+ if to_write:
+ cls.write(*to_write)
+
+
+class UserRole(ModelSQL, ModelView):
+ "User Role"
+ __name__ = 'res.user.role'
+ user = fields.Many2One(
+ 'res.user', "User", ondelete='CASCADE', required=True)
+ role = fields.Many2One('res.role', "Role", required=True)
+ from_date = fields.DateTime(
+ "From Date",
+ domain=[
+ If(Eval('from_date') & Eval('to_date'),
+ ('from_date', '<=', Eval('to_date', None)),
+ ()),
+ ])
+ to_date = fields.DateTime(
+ "To Date",
+ domain=[
+ If(Eval('from_date') & Eval('to_date'),
+ ('to_date', '>=', Eval('from_date', None)),
+ ()),
+ ])
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls._order.insert(0, ('from_date', 'DESC NULLS FIRST'))
+ cls._order.insert(1, ('to_date', 'ASC NULLS FIRST'))
+
+ def valid(self, date):
+ from_date = self.from_date or dt.datetime.min
+ to_date = self.to_date or dt.datetime.max
+ return from_date <= date <= to_date
diff --git a/modules/user_role/res.xml b/modules/user_role/res.xml
new file mode 100644
index 0000000000..e8c6bf33b4
--- /dev/null
+++ b/modules/user_role/res.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+ res.role
+ form
+ role_form
+
+
+
+ res.role
+ tree
+ role_list
+
+
+
+ Roles
+ res.role
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ res.user
+
+ user_form
+
+
+
+ res.user.role
+ form
+ user_role_form
+
+
+
+ res.user.role
+ tree
+ user_role_list
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ res.user|sync_roles
+
+ days
+
+
+
diff --git a/modules/user_role/setup.py b/modules/user_role/setup.py
new file mode 100755
index 0000000000..af0547f2ea
--- /dev/null
+++ b/modules/user_role/setup.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname):
+ return io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_user_role'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = []
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [get_require_version('proteus')]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module to manage role on user',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/user_role',
+ },
+ keywords='user role group access',
+ package_dir={'trytond.modules.user_role': '.'},
+ packages=(
+ ['trytond.modules.user_role']
+ + ['trytond.modules.user_role.%s' % p for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.user_role': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: Finnish',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Indonesian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ user_role = trytond.modules.user_role
+ """,
+ )
diff --git a/modules/user_role/tests/__init__.py b/modules/user_role/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/user_role/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/user_role/tests/scenario_user_role.rst b/modules/user_role/tests/scenario_user_role.rst
new file mode 100644
index 0000000000..dc5ea6b801
--- /dev/null
+++ b/modules/user_role/tests/scenario_user_role.rst
@@ -0,0 +1,88 @@
+==================
+User Role Scenario
+==================
+
+Imports::
+
+ >>> import datetime as dt
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+
+Activate modules::
+
+ >>> config = activate_modules('user_role')
+
+Create some groups::
+
+ >>> Group = Model.get('res.group')
+ >>> groups = [Group(name="Group %s" % i) for i in range(5)]
+ >>> Group.save(groups)
+
+Create a role::
+
+ >>> Role = Model.get('res.role')
+ >>> role = Role(name="Role")
+ >>> role.groups.append(Group(groups[0].id))
+ >>> role.groups.append(Group(groups[1].id))
+ >>> role.save()
+
+Create a user with some groups::
+
+ >>> User = Model.get('res.user')
+ >>> user = User(login="user")
+ >>> user.groups.append(Group(groups[1].id))
+ >>> user.groups.append(Group(groups[2].id))
+ >>> user.groups.append(Group(groups[3].id))
+ >>> user.save()
+ >>> len(user.groups)
+ 3
+
+Set the role to the user::
+
+ >>> user_role = user.roles.new()
+ >>> user_role.role = role
+ >>> user.save()
+
+ >>> len(user.groups)
+ 2
+ >>> user.groups == [groups[0], groups[1]]
+ True
+
+Start the role in the future::
+
+ >>> user_role, = user.roles
+ >>> user_role.from_date = dt.datetime.now() + dt.timedelta(days=1)
+ >>> user_role.to_date = None
+ >>> user.save()
+
+ >>> len(user.groups)
+ 0
+
+End the role in the past::
+
+ >>> user_role, = user.roles
+ >>> user_role.from_date = None
+ >>> user_role.to_date = dt.datetime.now() - dt.timedelta(days=1)
+ >>> user.save()
+
+ >>> len(user.groups)
+ 0
+
+Start the role in the past and end in the future::
+
+ >>> user_role, = user.roles
+ >>> user_role.from_date = dt.datetime.now() - dt.timedelta(days=1)
+ >>> user_role.to_date = dt.datetime.now() + dt.timedelta(days=1)
+ >>> user.save()
+
+ >>> len(user.groups)
+ 2
+
+Changing groups to role::
+
+ >>> role.groups.append(Group(groups[4].id))
+ >>> role.save()
+
+ >>> user.reload()
+ >>> len(user.groups)
+ 3
diff --git a/modules/user_role/tests/test_module.py b/modules/user_role/tests/test_module.py
new file mode 100644
index 0000000000..6a6d509306
--- /dev/null
+++ b/modules/user_role/tests/test_module.py
@@ -0,0 +1,12 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class UserRoleTestCase(ModuleTestCase):
+ 'Test User Role module'
+ module = 'user_role'
+
+
+del ModuleTestCase
diff --git a/modules/user_role/tests/test_scenario.py b/modules/user_role/tests/test_scenario.py
new file mode 100644
index 0000000000..dc1d23e7e5
--- /dev/null
+++ b/modules/user_role/tests/test_scenario.py
@@ -0,0 +1,8 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.tests.test_tryton import load_doc_tests
+
+
+def load_tests(*args, **kwargs):
+ return load_doc_tests(__name__, __file__, *args, **kwargs)
diff --git a/modules/user_role/tox.ini b/modules/user_role/tox.ini
new file mode 100644
index 0000000000..1de67aa285
--- /dev/null
+++ b/modules/user_role/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/user_role/* -m unittest discover -s tests
+ coverage report --include=./**/user_role/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/user_role/tryton.cfg b/modules/user_role/tryton.cfg
new file mode 100644
index 0000000000..f5fb66be44
--- /dev/null
+++ b/modules/user_role/tryton.cfg
@@ -0,0 +1,7 @@
+[tryton]
+version=6.7.0
+depends:
+ ir
+ res
+xml:
+ res.xml
diff --git a/modules/user_role/view/role_form.xml b/modules/user_role/view/role_form.xml
new file mode 100644
index 0000000000..29e71a9b75
--- /dev/null
+++ b/modules/user_role/view/role_form.xml
@@ -0,0 +1,8 @@
+
+
+
diff --git a/modules/user_role/view/role_list.xml b/modules/user_role/view/role_list.xml
new file mode 100644
index 0000000000..b4d89538b1
--- /dev/null
+++ b/modules/user_role/view/role_list.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/modules/user_role/view/user_form.xml b/modules/user_role/view/user_form.xml
new file mode 100644
index 0000000000..df84ab12ee
--- /dev/null
+++ b/modules/user_role/view/user_form.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/user_role/view/user_role_form.xml b/modules/user_role/view/user_role_form.xml
new file mode 100644
index 0000000000..dcc6f1a273
--- /dev/null
+++ b/modules/user_role/view/user_role_form.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/modules/user_role/view/user_role_list.xml b/modules/user_role/view/user_role_list.xml
new file mode 100644
index 0000000000..cc42201c70
--- /dev/null
+++ b/modules/user_role/view/user_role_list.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/web_shop/.drone.yml b/modules/web_shop/.drone.yml
new file mode 100644
index 0000000000..cb4fbecb4d
--- /dev/null
+++ b/modules/web_shop/.drone.yml
@@ -0,0 +1,70 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/web_shop/.flake8 b/modules/web_shop/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/web_shop/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/web_shop/.isort.cfg b/modules/web_shop/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/web_shop/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/web_shop/CHANGELOG b/modules/web_shop/CHANGELOG
new file mode 100644
index 0000000000..412f501d94
--- /dev/null
+++ b/modules/web_shop/CHANGELOG
@@ -0,0 +1,18 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.4.0 - 2022-05-02
+* Bug fixes (see mercurial logs for details)
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+* Bug fixes (see mercurial logs for details)
+* Add web shop check box to product image
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+
+Version 5.8.0 - 2020-11-02
+* Initial release
diff --git a/modules/web_shop/COPYRIGHT b/modules/web_shop/COPYRIGHT
new file mode 100644
index 0000000000..77b68b5df9
--- /dev/null
+++ b/modules/web_shop/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2020-2022 Cédric Krier
+Copyright (C) 2020-2022 B2CK
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/web_shop/LICENSE b/modules/web_shop/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/web_shop/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/web_shop/MANIFEST.in b/modules/web_shop/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/web_shop/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/web_shop/README.rst b/modules/web_shop/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/web_shop/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/web_shop/__init__.py b/modules/web_shop/__init__.py
new file mode 100644
index 0000000000..be3b04238d
--- /dev/null
+++ b/modules/web_shop/__init__.py
@@ -0,0 +1,30 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+__all__ = ['register']
+
+from . import product, sale, web
+
+
+def register():
+ Pool.register(
+ web.Shop,
+ web.Shop_Warehouse,
+ web.Shop_Product,
+ web.Shop_ProductCategory,
+ web.User,
+ product.Template,
+ product.Product,
+ product.Category,
+ sale.Sale,
+ module='web_shop', type_='model')
+ Pool.register(
+ web.ShopAttribute,
+ web.Shop_Attribute,
+ product.Attribute,
+ module='web_shop', type_='model', depends=['product_attribute'])
+ Pool.register(
+ product.Image,
+ module='web_shop', type_='model', depends=['product_image'])
diff --git a/modules/web_shop/doc/index.rst b/modules/web_shop/doc/index.rst
new file mode 100644
index 0000000000..ca1a1a8572
--- /dev/null
+++ b/modules/web_shop/doc/index.rst
@@ -0,0 +1,5 @@
+Web Shop Module
+###############
+
+The web_shop module provides facilities to store configuration of online web
+shop.
diff --git a/modules/web_shop/locale/bg.po b/modules/web_shop/locale/bg.po
new file mode 100644
index 0000000000..f8cf3bc30a
--- /dev/null
+++ b/modules/web_shop/locale/bg.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr ""
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr ""
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/locale/ca.po b/modules/web_shop/locale/ca.po
new file mode 100644
index 0000000000..e86ec8d280
--- /dev/null
+++ b/modules/web_shop/locale/ca.po
@@ -0,0 +1,223 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr "Tendes web"
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr "Tendes web"
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr "Tenda Web"
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr "Descripció tenda web"
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr "Tendes web"
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr "Descripció tenda web"
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr "ID Web"
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr "Tenda Web"
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr "Atributs"
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr "Atributes eliminats"
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr "Categories"
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr "Categories eliminades"
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr "Moneda"
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr "Tercer Invitat"
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr "Idioma"
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr "Nom"
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr "Productes"
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr "Productes eliminats"
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr "Tipus"
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr "Magatzems"
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr "Atribut"
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr "Tenda"
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr "Categoria"
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr "Tenda"
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr "Producte"
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr "Tenda"
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr "Tenda"
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr "Magatzem"
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr "Adreça de facturació"
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr "Adreça d'enviament"
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr "La llista de tendes online on s'ha publicat l'atribut."
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr "La llista de tendes on esta publicada la categoria."
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr "La llista de tendes on esta publicat el producte."
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr "La llista d'atributs a publicar."
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr "La llista d'atributs a despublicar."
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr "La llsita de categories a publicar."
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr "La llsita de categories a despublicar."
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr "La llsita de productes a publicar."
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr "La llsita de productes a despublicar."
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr "El front-end utiltizat per aquesta tenda."
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr "Tendes web"
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+"Per a processar la venda \"%(sale)s\" heu de seleccionar un tercer diferent "
+"del invitat \"%(party)s\"."
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr "El ID de la tenda web ha de ser únic."
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr "El nom de la tenda ha de ser únic."
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr "Usuari a les empreses"
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr "Tendes web"
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr "Tenda Web"
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr "Tenda Web - Atribut"
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr "Tenda web - Categoria de producte"
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr "Tenda web - Producte"
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr "Tenda web - Magatzem"
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr "Edita"
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr "Productes"
diff --git a/modules/web_shop/locale/cs.po b/modules/web_shop/locale/cs.po
new file mode 100644
index 0000000000..f8cf3bc30a
--- /dev/null
+++ b/modules/web_shop/locale/cs.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr ""
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr ""
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/locale/de.po b/modules/web_shop/locale/de.po
new file mode 100644
index 0000000000..6af9c7bb81
--- /dev/null
+++ b/modules/web_shop/locale/de.po
@@ -0,0 +1,223 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr "Webshops"
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr "Webshops"
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr "Webshop"
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr "Webshop Beschreibung"
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr "Webshops"
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr "Webshop Beschreibung"
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr "Web ID"
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr "Webshop"
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr "Attribute"
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr "Entfernte Attribute"
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr "Kategorien"
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr "Entfernte Kategorien"
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr "Unternehmen"
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr "Währung"
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr "Partei für Gäste"
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr "Sprache"
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr "Name"
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr "Artikel"
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr "Entfernte Artikel"
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr "Typ"
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr "Logistikstandorte"
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr "Attribut"
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr "Webshop"
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr "Kategorie"
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr "Webshop"
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr "Artikel"
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr "Webshop"
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr "Webshop"
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr "Logistikstandort"
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr "Rechnungsadresse"
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr "Lieferadresse"
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr "Die Liste der Webshops auf denen das Attribut veröffentlicht wird."
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr "Die Liste von Webshop auf dem die Kategorie veröffentlicht wird."
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr "Die Liste der Webshops in denen der Artikel veröffentlicht wird."
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr "Liste der zu veröffentlichenden Attribute."
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr "Liste der von der Veröffentlichung zurückzuziehenden Artikel."
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr "Liste der zu veröffentlichenden Kategorien."
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr "Liste der von der Veröffentlichung zurückzuziehenden Kategorien."
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr "Liste der zu veröffentlichenden Artikel."
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr "Liste der von der Veröffentlichung zurückzuziehenden Artikel."
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr "Das für den Webshop genutzte Frontend."
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr "Webshops"
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+"Um Verkauf \"%(sale)s\" auszuführen muss eine andere Partei als die "
+"Gastpartei \"%(party)s\" ausgewählt werden."
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr "Die Web ID auf dem Verkauf muss eindeutig sein."
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr "Der Name des Webshops muss eindeutig sein."
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr "Benutzer im Unternehmen"
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr "Webshops"
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr "Webshop"
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr "Webshop - Attribut"
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr "Webshop - Artikelkategorie"
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr "Webshop - Artikel"
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr "Webshop - Logistikstandort"
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr "Bearbeiten"
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr "Artikel"
diff --git a/modules/web_shop/locale/es.po b/modules/web_shop/locale/es.po
new file mode 100644
index 0000000000..f06a9fee85
--- /dev/null
+++ b/modules/web_shop/locale/es.po
@@ -0,0 +1,223 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr "Tiendas Web"
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr "Tiendas Web"
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr "Tienda Web"
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr "Descripción tienda web"
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr "Tiendas Web"
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr "Descripción tienda web"
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr "ID Web"
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr "Tienda Web"
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr "Atributos"
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr "Atributos eliminados"
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr "Categorías"
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr "Categorías eliminadas"
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr "Empresa"
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr "Moneda"
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr "Tercero invitado"
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr "Idioma"
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr "Nombre"
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr "Productos"
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr "Productos Eliminados"
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr "Tipo"
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr "Almacenes"
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr "Atributo"
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr "Tienda"
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr "Categoría"
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr "Tienda"
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr "Producto"
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr "Tienda"
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr "Tienda"
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr "Almacén"
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr "Dirección de facturación"
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr "Dirección de envío"
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr "La lista de tiendas web donde se publica el atributo."
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr "La lista de tiendas en que la categoría esta pública."
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr "La lista de tiendas en que el producto se ha publicado."
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr "La lista de atributos a publicar."
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr "La lista de atributos a despublicar."
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr "La lista de categorias a publicar."
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr "La lista de categorias a despublicar."
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr "La lista de produtos a publicar."
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr "La lista de categorias a despublicar."
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr "El frontend utilizado para la tienda web."
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr "Tiendas Web"
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+"Para procesar la venta \"%(sale)s\" debéis seleccionar un cliente distinto "
+"al invitado\"%(party)s\"."
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr "El id web de la venta debe ser único."
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr "El nombre de la tienda debe ser único."
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr "Usuario en las empresas"
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr "Tiendas Web"
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr "Tienda Web"
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr "Tienda Web - Atributo"
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr "Tienda Web - Categoría Producto"
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr "Tienda Web - Producto"
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr "Tienda Web - Almacén"
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr "Editar"
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr "Productos"
diff --git a/modules/web_shop/locale/es_419.po b/modules/web_shop/locale/es_419.po
new file mode 100644
index 0000000000..f8cf3bc30a
--- /dev/null
+++ b/modules/web_shop/locale/es_419.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr ""
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr ""
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/locale/et.po b/modules/web_shop/locale/et.po
new file mode 100644
index 0000000000..f8cf3bc30a
--- /dev/null
+++ b/modules/web_shop/locale/et.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr ""
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr ""
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/locale/fa.po b/modules/web_shop/locale/fa.po
new file mode 100644
index 0000000000..f8cf3bc30a
--- /dev/null
+++ b/modules/web_shop/locale/fa.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr ""
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr ""
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/locale/fi.po b/modules/web_shop/locale/fi.po
new file mode 100644
index 0000000000..f8cf3bc30a
--- /dev/null
+++ b/modules/web_shop/locale/fi.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr ""
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr ""
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/locale/fr.po b/modules/web_shop/locale/fr.po
new file mode 100644
index 0000000000..260ab03ec6
--- /dev/null
+++ b/modules/web_shop/locale/fr.po
@@ -0,0 +1,224 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr "Boutiques en ligne"
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr "Boutiques en ligne"
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr "Boutique en ligne"
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr "Description de la boutique en ligne"
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr "Boutiques en ligne"
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr "Description de la boutique en ligne"
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr "ID Web"
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr "Boutique en ligne"
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr "Attributs"
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr "Attributs supprimés"
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr "Catégories"
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr "Catégories supprimées"
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr "Société"
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr "Devise"
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr "Tiers invité"
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr "Langue"
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr "Nom"
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr "Produits"
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr "Produits supprimés"
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr "Type"
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr "Entrepôts"
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr "Attribut"
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr "Boutique"
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr "Catégorie"
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr "Boutique"
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr "Produit"
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr "Boutique"
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr "Boutique"
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr "Entrepôt"
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr "Adresse de facturation"
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr "Adresse d'expédition"
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr "La liste des boutiques en ligne sur lesquelles l'attribut est publié."
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+"La liste des boutiques en ligne sur lesquelles la catégorie est publiée."
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr "La liste des boutiques en ligne sur lesquelles le produit est publié."
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr "La liste des attributs à publier."
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr "La liste des attributs à dépublier."
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr "La liste des catégories à publier."
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr "La liste des catégories à dépublier."
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr "La liste des produits à publier."
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr "La liste des produits à dépublier."
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr "Le frontal utilisé pour la boutique en ligne."
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr "Boutiques en ligne"
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+"Pour traiter la vente « %(sale)s », vous devez sélectionner un autre tiers à"
+" la place de l'invité « %(party)s »."
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr "L'ID web de la vente doit être unique."
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr "Le nom de la boutique en ligne doit être unique."
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr "Utilisateur dans les sociétés"
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr "Boutiques en ligne"
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr "Boutique en ligne"
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr "Boutique Web - Attribut"
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr "Boutique en ligne - Catégorie de produit"
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr "Boutique en ligne - Produit"
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr "Boutique en ligne - Entrepôt"
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr "Éditer"
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr "Produits"
diff --git a/modules/web_shop/locale/hu.po b/modules/web_shop/locale/hu.po
new file mode 100644
index 0000000000..c878930fa8
--- /dev/null
+++ b/modules/web_shop/locale/hu.po
@@ -0,0 +1,224 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr "Webáruházak"
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr "Webáruházak"
+
+#, fuzzy
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr "Webáruház"
+
+#, fuzzy
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr "Webáruházak"
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr "Webáruházak"
+
+#, fuzzy
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr "Webáruházak"
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr "Webáruház"
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr "Jellemző értékek"
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr "Kategóriák"
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr "Cég"
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr "Pénznem"
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr "Vendég ügyfél"
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr "Nyelv"
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr "Név"
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr "Termékek"
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr "Típus"
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr "Raktárak"
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr "Jellemző érték"
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr "Bolt"
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr "Kategória"
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr "Bolt"
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr "Termék"
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr "Bolt"
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr "Bolt"
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr "Raktár"
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr "Számlázási cím"
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr "Szállítási cím"
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr "Webáruházak"
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr "Webáruházak"
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr "Webáruház"
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr "Termékek"
diff --git a/modules/web_shop/locale/id.po b/modules/web_shop/locale/id.po
new file mode 100644
index 0000000000..f513569bde
--- /dev/null
+++ b/modules/web_shop/locale/id.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr "Perusahaan"
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr "Mata Uang"
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr "Bahasa"
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr "Nama"
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr "Toko"
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr "Kategori"
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr "Toko"
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr "Produk"
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr "Toko"
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr "Toko"
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr "Gudang"
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr "Alamat Faktur"
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr "Sunting"
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr "Produk-Produk"
diff --git a/modules/web_shop/locale/it.po b/modules/web_shop/locale/it.po
new file mode 100644
index 0000000000..396e43c16a
--- /dev/null
+++ b/modules/web_shop/locale/it.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr "Attributi"
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr "Valuta"
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr "Magazzini"
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr "Prodotto"
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr "Magazzino"
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr "Indirizzo di fatturazione"
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr "indirizzo di spedizione"
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/locale/lo.po b/modules/web_shop/locale/lo.po
new file mode 100644
index 0000000000..f8cf3bc30a
--- /dev/null
+++ b/modules/web_shop/locale/lo.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr ""
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr ""
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/locale/lt.po b/modules/web_shop/locale/lt.po
new file mode 100644
index 0000000000..f8cf3bc30a
--- /dev/null
+++ b/modules/web_shop/locale/lt.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr ""
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr ""
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/locale/nl.po b/modules/web_shop/locale/nl.po
new file mode 100644
index 0000000000..e499fd0f68
--- /dev/null
+++ b/modules/web_shop/locale/nl.po
@@ -0,0 +1,225 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr "Webwinkels"
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr "Webwinkels"
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr "Webwinkel"
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr "Beschrijving van de webshop"
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr "Webwinkels"
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr "Beschrijving van de webshop"
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr "Web-ID"
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr "Webwinkels"
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr "attributen"
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr "verijderde attributen"
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr "Categorieën"
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr "verwijderde Categorieën"
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr "Bedrijf"
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr "Valuta"
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr "Gast Relatie"
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr "Taal"
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr "Naam"
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr "Producten"
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr "Verwijderde Producten"
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr "Type"
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr "Magazijn"
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr "Attribuut"
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr "Winkel"
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr "Categorie"
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr "Winkel"
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr "Product"
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr "Winkel"
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr "Winkel"
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr "Magazijn"
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr "Factuuradres"
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr "Afleveradres"
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr "De lijst met webwinkels waarop het attribuut is gepubliceerd."
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr "De lijst met webwinkels waarop de categorie is gepubliceerd."
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr "De lijst met webwinkels waarop het product is gepubliceerd."
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr "De lijst met te publiceren kenmerken."
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr "De lijst met te publiceren kenmerken."
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr "De lijst met te publiceren categorieën."
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+"De lijst met categorieën waarvan de publicatie ongedaan moet worden gemaakt."
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr "De lijst met te publiceren producten."
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+"De lijst met producten waarvan de publicatie ongedaan moet worden gemaakt."
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr "De front-end die wordt gebruikt voor de webshop."
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr "Webwinkels"
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+"Om de verkoop \"%(sale)s\" te verwerken, moet u een andere relatie "
+"selecteren in plaats van de gast \"%(party)s\"."
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr "De web-ID van de verkoop moet uniek zijn."
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr "De naam van de webshop moet uniek zijn."
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr "Gebruiker in het bedrijf"
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr "Webwinkels"
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr "Webwinkels"
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr "Webwinkel - Kenmerk"
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr "Webwinkel - Productcategorie"
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr "Webwinkel - Product"
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr "Webwinkel - Magazijn"
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr "Bewerk"
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr "Producten"
diff --git a/modules/web_shop/locale/pl.po b/modules/web_shop/locale/pl.po
new file mode 100644
index 0000000000..f8cf3bc30a
--- /dev/null
+++ b/modules/web_shop/locale/pl.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr ""
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr ""
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/locale/pt.po b/modules/web_shop/locale/pt.po
new file mode 100644
index 0000000000..f8cf3bc30a
--- /dev/null
+++ b/modules/web_shop/locale/pt.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr ""
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr ""
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/locale/ro.po b/modules/web_shop/locale/ro.po
new file mode 100644
index 0000000000..f8cf3bc30a
--- /dev/null
+++ b/modules/web_shop/locale/ro.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr ""
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr ""
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/locale/ru.po b/modules/web_shop/locale/ru.po
new file mode 100644
index 0000000000..f8cf3bc30a
--- /dev/null
+++ b/modules/web_shop/locale/ru.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr ""
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr ""
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/locale/sl.po b/modules/web_shop/locale/sl.po
new file mode 100644
index 0000000000..f8cf3bc30a
--- /dev/null
+++ b/modules/web_shop/locale/sl.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr ""
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr ""
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/locale/tr.po b/modules/web_shop/locale/tr.po
new file mode 100644
index 0000000000..f8cf3bc30a
--- /dev/null
+++ b/modules/web_shop/locale/tr.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr ""
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr ""
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/locale/uk.po b/modules/web_shop/locale/uk.po
new file mode 100644
index 0000000000..54ffc4cfc2
--- /dev/null
+++ b/modules/web_shop/locale/uk.po
@@ -0,0 +1,223 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr "Веб-магазини"
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr "Веб-магазини"
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr "Веб-магазин"
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr "Опис веб-магазину"
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr "Веб-магазини"
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr "Опис веб-магазину"
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr "Веб-ID"
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr "Веб-магазин"
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr "Атрибути"
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr "Атрибути видалено"
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr "Категорії"
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr "Категорії видалено"
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr "Компанія"
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr "Валюта"
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr "Гостьова особа"
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr "Мова"
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr "Назва"
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr "Товари"
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr "Товари видалено"
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr "Тип"
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr "Склади"
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr "Атрибут"
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr "Магазин"
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr "Категорія"
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr "Магазин"
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr "Товар"
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr "Магазин"
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr "Магазин"
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr "Склад"
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr "Адреса рахунку"
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr "Адреса відвантаження"
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr "Список веб-магазинів, у яких опубліковано атрибут."
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr "Список веб-магазинів, у яких опублікована категорія."
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr "Список веб-магазинів, у яких опубліковано товар."
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr "Список атрибутів для публікації."
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr "Список атрибутів, публікацію яких потрібно скасувати."
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr "Список категорій для публікації."
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr "Список категорій, публікацію яких потрібно скасувати."
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr "Список товарів для публікації."
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr "Список товарів, публікацію яких потрібно скасувати."
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr "Інтерфейс, який використовується для веб-магазину."
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr "Веб-магазини"
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+"Щоб обробити продаж \"%(sale)s\", ви повинні вибрати іншу особу замість "
+"гостя \"%(party)s\"."
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr "Веб-ID на продаж має бути унікальним."
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr "Назва веб-магазину має бути унікальною."
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr "Користувач у компаніях"
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr "Веб-магазини"
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr "Веб-магазин"
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr "Веб-магазин – Атрибут"
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr "Веб-магазин – Категорія товару"
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr "Веб-магазин - Товар"
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr "Веб-магазин - Склад"
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr "Редагувати"
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr "Товари"
diff --git a/modules/web_shop/locale/zh_CN.po b/modules/web_shop/locale/zh_CN.po
new file mode 100644
index 0000000000..f8cf3bc30a
--- /dev/null
+++ b/modules/web_shop/locale/zh_CN.po
@@ -0,0 +1,221 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgctxt "field:product.attribute,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.category,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.image,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:product.product,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:product.product,web_shops:"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "field:product.template,web_shop_description:"
+msgid "Web Shop Description"
+msgstr ""
+
+msgctxt "field:sale.sale,web_id:"
+msgid "Web ID"
+msgstr ""
+
+msgctxt "field:sale.sale,web_shop:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "field:web.shop,attributes:"
+msgid "Attributes"
+msgstr ""
+
+msgctxt "field:web.shop,attributes_removed:"
+msgid "Attributes Removed"
+msgstr ""
+
+msgctxt "field:web.shop,categories:"
+msgid "Categories"
+msgstr ""
+
+msgctxt "field:web.shop,categories_removed:"
+msgid "Categories Removed"
+msgstr ""
+
+msgctxt "field:web.shop,company:"
+msgid "Company"
+msgstr ""
+
+msgctxt "field:web.shop,currency:"
+msgid "Currency"
+msgstr ""
+
+msgctxt "field:web.shop,guest_party:"
+msgid "Guest Party"
+msgstr ""
+
+msgctxt "field:web.shop,language:"
+msgid "Language"
+msgstr ""
+
+msgctxt "field:web.shop,name:"
+msgid "Name"
+msgstr ""
+
+msgctxt "field:web.shop,products:"
+msgid "Products"
+msgstr ""
+
+msgctxt "field:web.shop,products_removed:"
+msgid "Products Removed"
+msgstr ""
+
+msgctxt "field:web.shop,type:"
+msgid "Type"
+msgstr ""
+
+msgctxt "field:web.shop,warehouses:"
+msgid "Warehouses"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,attribute:"
+msgid "Attribute"
+msgstr ""
+
+msgctxt "field:web.shop-product.attribute,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,category:"
+msgid "Category"
+msgstr ""
+
+msgctxt "field:web.shop-product.category,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,product:"
+msgid "Product"
+msgstr ""
+
+msgctxt "field:web.shop-product.product,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,shop:"
+msgid "Shop"
+msgstr ""
+
+msgctxt "field:web.shop-stock.location,warehouse:"
+msgid "Warehouse"
+msgstr ""
+
+msgctxt "field:web.user,invoice_address:"
+msgid "Invoice Address"
+msgstr ""
+
+msgctxt "field:web.user,shipment_address:"
+msgid "Shipment Address"
+msgstr ""
+
+msgctxt "help:product.attribute,web_shops:"
+msgid "The list of web shops on which the attribute is published."
+msgstr ""
+
+msgctxt "help:product.category,web_shops:"
+msgid "The list of web shops on which the category is published."
+msgstr ""
+
+msgctxt "help:product.product,web_shops:"
+msgid "The list of web shops on which the product is published."
+msgstr ""
+
+msgctxt "help:web.shop,attributes:"
+msgid "The list of attributes to publish."
+msgstr ""
+
+msgctxt "help:web.shop,attributes_removed:"
+msgid "The list of attributes to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,categories:"
+msgid "The list of categories to publish."
+msgstr ""
+
+msgctxt "help:web.shop,categories_removed:"
+msgid "The list of categories to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,products:"
+msgid "The list of products to publish."
+msgstr ""
+
+msgctxt "help:web.shop,products_removed:"
+msgid "The list of products to unpublish."
+msgstr ""
+
+msgctxt "help:web.shop,type:"
+msgid "The front-end used for the web shop."
+msgstr ""
+
+msgctxt "model:ir.action,name:act_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_invalid_party"
+msgid ""
+"To process the sale \"%(sale)s\" you must select another party instead of "
+"the guest \"%(party)s\"."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_sale_web_id_unique"
+msgid "The web ID on the sale must be unique."
+msgstr ""
+
+msgctxt "model:ir.message,text:msg_shop_name_unique"
+msgid "The web shop name must be unique."
+msgstr ""
+
+msgctxt "model:ir.rule.group,name:rule_group_shop_companies"
+msgid "User in companies"
+msgstr ""
+
+msgctxt "model:ir.ui.menu,name:menu_shop"
+msgid "Web Shops"
+msgstr ""
+
+msgctxt "model:web.shop,name:"
+msgid "Web Shop"
+msgstr ""
+
+msgctxt "model:web.shop-product.attribute,name:"
+msgid "Web Shop - Attribute"
+msgstr ""
+
+msgctxt "model:web.shop-product.category,name:"
+msgid "Web Shop - Product Category"
+msgstr ""
+
+msgctxt "model:web.shop-product.product,name:"
+msgid "Web Shop - Product"
+msgstr ""
+
+msgctxt "model:web.shop-stock.location,name:"
+msgid "Web Shop - Warehouse"
+msgstr ""
+
+msgctxt "view:product.template:"
+msgid "Edit"
+msgstr ""
+
+msgctxt "view:web.shop:"
+msgid "Products"
+msgstr ""
diff --git a/modules/web_shop/message.xml b/modules/web_shop/message.xml
new file mode 100644
index 0000000000..8426d012ec
--- /dev/null
+++ b/modules/web_shop/message.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ The web shop name must be unique.
+
+
+ To process the sale "%(sale)s" you must select another party instead of the guest "%(party)s".
+
+
+ The web ID on the sale must be unique.
+
+
+
diff --git a/modules/web_shop/product.py b/modules/web_shop/product.py
new file mode 100644
index 0000000000..2446ae6807
--- /dev/null
+++ b/modules/web_shop/product.py
@@ -0,0 +1,50 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.config import config
+from trytond.model import fields
+from trytond.pool import PoolMeta
+from trytond.pyson import Eval
+
+if not config.get('html', 'plugins-product.template-web_shop_description'):
+ config.set(
+ 'html', 'plugins-product.template-web_shop_description', 'fullpage')
+
+
+class Template(metaclass=PoolMeta):
+ __name__ = 'product.template'
+
+ web_shop_description = fields.Text("Web Shop Description", translate=True)
+
+
+class Product(metaclass=PoolMeta):
+ __name__ = 'product.product'
+
+ web_shops = fields.Many2Many(
+ 'web.shop-product.product', 'product', 'shop', "Web Shops",
+ states={
+ 'invisible': ~Eval('salable'),
+ },
+ help="The list of web shops on which the product is published.")
+
+
+class Category(metaclass=PoolMeta):
+ __name__ = 'product.category'
+
+ web_shops = fields.Many2Many(
+ 'web.shop-product.category', 'category', 'shop', "Web Shops",
+ help="The list of web shops on which the category is published.")
+
+
+class Attribute(metaclass=PoolMeta):
+ __name__ = 'product.attribute'
+
+ web_shops = fields.Many2Many(
+ 'web.shop-product.attribute', 'attribute', 'shop', "Web Shops",
+ help="The list of web shops on which the attribute is published.")
+
+
+class Image(metaclass=PoolMeta):
+ __name__ = 'product.image'
+
+ web_shop = fields.Boolean("Web Shop")
diff --git a/modules/web_shop/product.xml b/modules/web_shop/product.xml
new file mode 100644
index 0000000000..869358fca1
--- /dev/null
+++ b/modules/web_shop/product.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+ product.template
+
+ product_template_form
+
+
+
+ product.product
+
+ product_product_form
+
+
+
+ product.category
+
+ product_category_form
+
+
+
+
+
+ product.attribute
+
+ product_attribute_form
+
+
+
+
+
+ product.image
+
+ product_image_list
+
+
+
+ product.image
+
+ product_image_form
+
+
+
+ product.image
+
+ product_image_form
+
+
+
diff --git a/modules/web_shop/sale.py b/modules/web_shop/sale.py
new file mode 100644
index 0000000000..2180d4f6fe
--- /dev/null
+++ b/modules/web_shop/sale.py
@@ -0,0 +1,65 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from secrets import token_hex
+
+from sql.conditionals import NullIf
+from sql.operators import Equal
+
+from trytond.i18n import gettext
+from trytond.model import Exclude, fields
+from trytond.modules.sale.exceptions import SaleValidationError
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Bool, Eval
+
+
+class Sale(metaclass=PoolMeta):
+ __name__ = 'sale.sale'
+
+ web_shop = fields.Many2One('web.shop', "Web Shop", ondelete='RESTRICT')
+ web_id = fields.Char(
+ "Web ID", strip=False,
+ states={
+ 'required': Bool(Eval('web_shop')),
+ 'readonly': ~Eval('web_id'),
+ })
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ t = cls.__table__()
+ cls._sql_constraints += [
+ ('web_id', Exclude(t, (NullIf(t.web_id, ''), Equal)),
+ 'web_shop.msg_sale_web_id_unique')
+ ]
+
+ @fields.depends('web_shop', 'web_id')
+ def on_change_web_shop(self, nbytes=None):
+ if self.web_shop and not self.web_id:
+ self.web_id = token_hex(nbytes)
+
+ @classmethod
+ def copy(cls, sales, default=None):
+ if default is None:
+ default = {}
+ else:
+ default = default.copy()
+ default.setdefault('web_shop', None)
+ default.setdefault('web_id', None)
+ return super().copy(sales, default=default)
+
+ @classmethod
+ def validate_fields(cls, sales, field_names):
+ pool = Pool()
+ WebShop = pool.get('web.shop')
+ super().validate_fields(sales, field_names)
+
+ if field_names & {'state', 'party'}:
+ web_shops = WebShop.search([])
+ guests = {s.guest_party for s in web_shops}
+ for sale in sales:
+ if (sale.state not in {'draft', 'cancelled'}
+ and sale.party in guests):
+ raise SaleValidationError(
+ gettext('web_shop.msg_sale_invalid_party',
+ sale=sale.rec_name,
+ party=sale.party.rec_name))
diff --git a/modules/web_shop/sale.xml b/modules/web_shop/sale.xml
new file mode 100644
index 0000000000..f06ff244bb
--- /dev/null
+++ b/modules/web_shop/sale.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ sale.sale
+
+ sale_form
+
+
+
diff --git a/modules/web_shop/setup.py b/modules/web_shop/setup.py
new file mode 100755
index 0000000000..b344f6b64f
--- /dev/null
+++ b/modules/web_shop/setup.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python3
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+import io
+import os
+import re
+from configparser import ConfigParser
+
+from setuptools import find_packages, setup
+
+
+def read(fname, slice=None):
+ content = io.open(
+ os.path.join(os.path.dirname(__file__), fname),
+ 'r', encoding='utf-8').read()
+ if slice:
+ content = '\n'.join(content.splitlines()[slice])
+ return content
+
+
+def get_require_version(name):
+ if minor_version % 2:
+ require = '%s >= %s.%s.dev0, < %s.%s'
+ else:
+ require = '%s >= %s.%s, < %s.%s'
+ require %= (name, major_version, minor_version,
+ major_version, minor_version + 1)
+ return require
+
+
+config = ConfigParser()
+config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
+info = dict(config.items('tryton'))
+for key in ('depends', 'extras_depend', 'xml'):
+ if key in info:
+ info[key] = info[key].strip().splitlines()
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
+major_version = int(major_version)
+minor_version = int(minor_version)
+name = 'trytond_web_shop'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+ major_version, minor_version)
+if minor_version % 2:
+ version = '%s.%s.dev0' % (major_version, minor_version)
+ download_url = (
+ 'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+ name[8:], name, version))
+local_version = []
+if os.environ.get('CI_JOB_ID'):
+ local_version.append(os.environ['CI_JOB_ID'])
+else:
+ for build in ['CI_BUILD_NUMBER', 'CI_JOB_NUMBER']:
+ if os.environ.get(build):
+ local_version.append(os.environ[build])
+ else:
+ local_version = []
+ break
+if local_version:
+ version += '+' + '.'.join(local_version)
+
+requires = []
+for dep in info.get('depends', []):
+ if not re.match(r'(ir|res)(\W|$)', dep):
+ requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
+
+tests_require = [
+ get_require_version('trytond_product_attribute'),
+ get_require_version('trytond_product_image'),
+ ]
+dependency_links = []
+if minor_version % 2:
+ dependency_links.append(
+ 'https://trydevpi.tryton.org/?local_version='
+ + '.'.join(local_version))
+
+setup(name=name,
+ version=version,
+ description='Tryton module that provides a common base for webshops',
+ long_description=read('README.rst'),
+ author='Tryton',
+ author_email='bugs@tryton.org',
+ url='http://www.tryton.org/',
+ download_url=download_url,
+ project_urls={
+ "Bug Tracker": 'https://bugs.tryton.org/',
+ "Documentation": 'https://docs.tryton.org/',
+ "Forum": 'https://www.tryton.org/forum',
+ "Source Code": 'https://hg.tryton.org/modules/web_shop',
+ },
+ keywords='webshop ecommerce',
+ package_dir={'trytond.modules.web_shop': '.'},
+ packages=(
+ ['trytond.modules.web_shop']
+ + ['trytond.modules.web_shop.%s' % p for p in find_packages()]
+ ),
+ package_data={
+ 'trytond.modules.web_shop': (info.get('xml', [])
+ + ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
+ 'icons/*.svg', 'tests/*.rst']),
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Intended Audience :: Legal Industry',
+ 'License :: OSI Approved :: '
+ 'GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: Bulgarian',
+ 'Natural Language :: Catalan',
+ 'Natural Language :: Chinese (Simplified)',
+ 'Natural Language :: Czech',
+ 'Natural Language :: Dutch',
+ 'Natural Language :: English',
+ 'Natural Language :: French',
+ 'Natural Language :: German',
+ 'Natural Language :: Hungarian',
+ 'Natural Language :: Italian',
+ 'Natural Language :: Persian',
+ 'Natural Language :: Polish',
+ 'Natural Language :: Portuguese (Brazilian)',
+ 'Natural Language :: Romanian',
+ 'Natural Language :: Russian',
+ 'Natural Language :: Slovenian',
+ 'Natural Language :: Spanish',
+ 'Natural Language :: Turkish',
+ 'Natural Language :: Ukrainian',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: Implementation :: CPython',
+ 'Topic :: Office/Business',
+ ],
+ license='GPL-3',
+ python_requires='>=3.7',
+ install_requires=requires,
+ extras_require={
+ 'test': tests_require,
+ },
+ dependency_links=dependency_links,
+ zip_safe=False,
+ entry_points="""
+ [trytond.modules]
+ web_shop = trytond.modules.web_shop
+ """,
+ )
diff --git a/modules/web_shop/tests/__init__.py b/modules/web_shop/tests/__init__.py
new file mode 100644
index 0000000000..4effdfa4a2
--- /dev/null
+++ b/modules/web_shop/tests/__init__.py
@@ -0,0 +1,2 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
diff --git a/modules/web_shop/tests/test_module.py b/modules/web_shop/tests/test_module.py
new file mode 100644
index 0000000000..923b136ea0
--- /dev/null
+++ b/modules/web_shop/tests/test_module.py
@@ -0,0 +1,14 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.modules.company.tests import CompanyTestMixin
+from trytond.tests.test_tryton import ModuleTestCase
+
+
+class WebShopTestCase(CompanyTestMixin, ModuleTestCase):
+ 'Test Web Shop module'
+ module = 'web_shop'
+ extras = ['product_attribute', 'product_image']
+
+
+del ModuleTestCase
diff --git a/modules/web_shop/tox.ini b/modules/web_shop/tox.ini
new file mode 100644
index 0000000000..d81f5f136b
--- /dev/null
+++ b/modules/web_shop/tox.ini
@@ -0,0 +1,17 @@
+[tox]
+envlist = {py37,py38,py39,py310}-{sqlite,postgresql}
+
+[testenv]
+extras = test
+commands =
+ coverage run --include=./**/web_shop/* -m unittest discover -s tests
+ coverage report --include=./**/web_shop/* --omit=*/tests/*
+deps =
+ coverage
+ postgresql: psycopg2 >= 2.7.0
+setenv =
+ sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
+ postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
+ sqlite: DB_NAME={env:SQLITE_NAME::memory:}
+ postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
+install_command = pip install --pre --find-links https://trydevpi.tryton.org/?local_version={env:CI_JOB_ID:{env:CI_BUILD_NUMBER:}.{env:CI_JOB_NUMBER:}} {opts} {packages}
diff --git a/modules/web_shop/tryton.cfg b/modules/web_shop/tryton.cfg
new file mode 100644
index 0000000000..3018d7850b
--- /dev/null
+++ b/modules/web_shop/tryton.cfg
@@ -0,0 +1,19 @@
+[tryton]
+version=6.7.0
+depends:
+ account
+ company
+ currency
+ ir
+ product
+ sale
+ stock
+ web_user
+extras_depend:
+ product_attribute
+ product_image
+xml:
+ web.xml
+ product.xml
+ sale.xml
+ message.xml
diff --git a/modules/web_shop/view/product_attribute_form.xml b/modules/web_shop/view/product_attribute_form.xml
new file mode 100644
index 0000000000..958e7a5351
--- /dev/null
+++ b/modules/web_shop/view/product_attribute_form.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/web_shop/view/product_category_form.xml b/modules/web_shop/view/product_category_form.xml
new file mode 100644
index 0000000000..35755ffbb2
--- /dev/null
+++ b/modules/web_shop/view/product_category_form.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
diff --git a/modules/web_shop/view/product_image_form.xml b/modules/web_shop/view/product_image_form.xml
new file mode 100644
index 0000000000..94d3d12709
--- /dev/null
+++ b/modules/web_shop/view/product_image_form.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/web_shop/view/product_image_list.xml b/modules/web_shop/view/product_image_list.xml
new file mode 100644
index 0000000000..5d7061c832
--- /dev/null
+++ b/modules/web_shop/view/product_image_list.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/web_shop/view/product_product_form.xml b/modules/web_shop/view/product_product_form.xml
new file mode 100644
index 0000000000..fbcb2cf2fd
--- /dev/null
+++ b/modules/web_shop/view/product_product_form.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/web_shop/view/product_template_form.xml b/modules/web_shop/view/product_template_form.xml
new file mode 100644
index 0000000000..992592108b
--- /dev/null
+++ b/modules/web_shop/view/product_template_form.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/web_shop/view/sale_form.xml b/modules/web_shop/view/sale_form.xml
new file mode 100644
index 0000000000..3c3e64c54b
--- /dev/null
+++ b/modules/web_shop/view/sale_form.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/web_shop/view/shop_attribute_form.xml b/modules/web_shop/view/shop_attribute_form.xml
new file mode 100644
index 0000000000..8bfd78e0b0
--- /dev/null
+++ b/modules/web_shop/view/shop_attribute_form.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/modules/web_shop/view/shop_form.xml b/modules/web_shop/view/shop_form.xml
new file mode 100644
index 0000000000..f157187138
--- /dev/null
+++ b/modules/web_shop/view/shop_form.xml
@@ -0,0 +1,32 @@
+
+
+
diff --git a/modules/web_shop/view/shop_list.xml b/modules/web_shop/view/shop_list.xml
new file mode 100644
index 0000000000..7b93f781d6
--- /dev/null
+++ b/modules/web_shop/view/shop_list.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/modules/web_shop/view/user_form.xml b/modules/web_shop/view/user_form.xml
new file mode 100644
index 0000000000..fe668dde95
--- /dev/null
+++ b/modules/web_shop/view/user_form.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/web_shop/web.py b/modules/web_shop/web.py
new file mode 100644
index 0000000000..97ec9a7efd
--- /dev/null
+++ b/modules/web_shop/web.py
@@ -0,0 +1,331 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from collections import defaultdict
+
+from sql import Literal
+from sql.operators import Equal
+
+from trytond.cache import Cache
+from trytond.model import (
+ DeactivableMixin, Exclude, ModelSQL, ModelView, fields)
+from trytond.pool import Pool, PoolMeta
+from trytond.pyson import Eval
+from trytond.transaction import Transaction
+
+
+class Many2ManyInactive(fields.Many2Many):
+
+ def get(self, ids, model, name, values=None):
+ with Transaction().set_context(inactive_test=True):
+ return super().get(ids, model, name, values=values)
+
+ def set(self, Model, name, ids, values, *args):
+ with Transaction().set_context(inactive_test=True):
+ return super().set(Model, name, ids, values, *args)
+
+
+class Inactivate(ModelSQL, DeactivableMixin):
+
+ @classmethod
+ def search_domain(cls, domain, active_test=True, tables=None):
+ context = Transaction().context
+ if context.get('inactive_test'):
+ domain = [domain, ('active', '=', False)]
+ return super().search_domain(
+ domain, active_test=active_test, tables=tables)
+
+ @classmethod
+ def delete(cls, records):
+ cls.copy([r for r in records if r.active and r.shop.to_sync],
+ default={
+ 'active': False,
+ })
+ super().delete(records)
+
+
+class Shop(DeactivableMixin, ModelSQL, ModelView):
+ "Web Shop"
+ __name__ = 'web.shop'
+
+ name = fields.Char("Name", required=True)
+ company = fields.Many2One('company.company', "Company", required=True)
+ currency = fields.Many2One('currency.currency', "Currency", required=True)
+ language = fields.Many2One(
+ 'ir.lang', "Language",
+ domain=[
+ ('translatable', '=', True),
+ ])
+ type = fields.Selection([
+ (None, ""),
+ ], "Type",
+ help="The front-end used for the web shop.")
+ warehouses = fields.Many2Many(
+ 'web.shop-stock.location', 'shop', 'warehouse', "Warehouses",
+ domain=[
+ ('type', '=', 'warehouse'),
+ ])
+ guest_party = fields.Many2One(
+ 'party.party', "Guest Party",
+ context={
+ 'company': Eval('company', -1),
+ },
+ depends={'company'})
+
+ products = fields.Many2Many(
+ 'web.shop-product.product', 'shop', 'product', "Products",
+ domain=[
+ ('salable', '=', True),
+ ],
+ context={
+ 'company': Eval('company', -1),
+ },
+ depends={'company'},
+ help="The list of products to publish.")
+ products_removed = Many2ManyInactive(
+ 'web.shop-product.product', 'shop', 'product', "Products Removed",
+ context={
+ 'company': Eval('company', -1),
+ },
+ depends={'company'},
+ help="The list of products to unpublish.")
+
+ categories = fields.Many2Many(
+ 'web.shop-product.category', 'shop', 'category', "Categories",
+ context={
+ 'company': Eval('company', -1),
+ },
+ depends={'company'},
+ help="The list of categories to publish.")
+ categories_removed = Many2ManyInactive(
+ 'web.shop-product.category', 'shop', 'category', "Categories Removed",
+ context={
+ 'company': Eval('company', -1),
+ },
+ depends={'company'},
+ help="The list of categories to unpublish.")
+
+ _name_cache = Cache('web.shop.name', context=False)
+
+ @property
+ def warehouse(self):
+ if self.warehouses:
+ return self.warehouses[0]
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+
+ t = cls.__table__()
+ cls._sql_constraints = [
+ ('name_unique', Exclude(t, (t.name, Equal),
+ where=t.active == Literal(True)),
+ 'web_shop.msg_shop_name_unique'),
+ ]
+
+ @classmethod
+ def default_company(cls):
+ return Transaction().context.get('company')
+
+ @classmethod
+ def default_currency(cls):
+ pool = Pool()
+ Company = pool.get('company.company')
+ company_id = cls.default_company()
+ if company_id:
+ company = Company(company_id)
+ return company.currency.id
+
+ @classmethod
+ def get(cls, name):
+ shop_id = cls._name_cache.get(name)
+ if not shop_id:
+ shop, = cls.search([('name', '=', name)])
+ cls._name_cache.set(name, shop.id)
+ else:
+ shop = cls(shop_id)
+ return shop
+
+ @classmethod
+ def write(cls, *args):
+ cls._name_cache.clear()
+ super().write(*args)
+
+ @classmethod
+ def delete(cls, shops):
+ cls._name_cache.clear()
+ super().delete(shops)
+
+ @property
+ def to_sync(self):
+ return False
+
+ def _customer_taxe_rule(self):
+ pool = Pool()
+ Configuration = pool.get('account.configuration')
+ config = Configuration(1)
+ return config.get_multivalue(
+ 'default_customer_tax_rule', company=self.company.id)
+
+ def get_context(self):
+ pool = Pool()
+ Date = pool.get('ir.date')
+ with Transaction().set_context(company=self.company.id):
+ today = Date.today()
+ return {
+ 'language': self.language.code if self.language else None,
+ 'company': self.company.id,
+ 'currency': self.currency.id,
+ 'locations': [w.id for w in self.warehouses],
+ 'stock_date_end': today,
+ 'stock_assign': True,
+ }
+
+ def get_products(self, pattern=None):
+ "Return the list of products with corresponding prices and taxes"
+ pool = Pool()
+ Date = pool.get('ir.date')
+ Product = pool.get('product.product')
+ Tax = pool.get('account.tax')
+ if pattern is None:
+ pattern = {}
+
+ with Transaction().set_context(**self.get_context()):
+ all_products = Product.browse(self.products)
+ today = Date.today()
+
+ customer_tax_rule = self._customer_taxe_rule()
+ taxes2products = defaultdict(list)
+ for product in all_products:
+ taxes = set()
+ for tax in product.customer_taxes_used:
+ if customer_tax_rule:
+ tax_ids = customer_tax_rule.apply(tax, pattern)
+ if tax_ids:
+ taxes.update(tax_ids)
+ continue
+ taxes.add(tax.id)
+ if customer_tax_rule:
+ tax_ids = customer_tax_rule.apply(None, pattern)
+ if tax_ids:
+ taxes.update(tax_ids)
+ taxes2products[tuple(sorted(taxes))].append(product)
+
+ prices, taxes = {}, {}
+ for tax_ids, products in taxes2products.items():
+ with Transaction().set_context(**self.get_context()):
+ products = Product.browse(products)
+ taxes_ = Tax.browse(tax_ids)
+ with Transaction().set_context(taxes=tax_ids):
+ prices.update(Product.get_sale_price(products))
+ for product in products:
+ price = prices[product.id]
+ if price is not None:
+ taxes[product.id] = sum(
+ t['amount'] for t in Tax.compute(
+ taxes_, price, 1, today))
+ else:
+ taxes[product.id] = None
+
+ return all_products, prices, taxes
+
+ def get_categories(self):
+ "Return the list of categories"
+ pool = Pool()
+ Category = pool.get('product.category')
+ with Transaction().set_context(**self.get_context()):
+ return Category.browse(self.categories)
+
+ def get_sale(self, party=None):
+ pool = Pool()
+ Sale = pool.get('sale.sale')
+ if not party:
+ party = self.guest_party
+ sale = Sale(party=party)
+ sale.company = self.company
+ sale.currency = self.currency
+ sale.warehouse = self.warehouse
+ sale.invoice_method = 'order'
+ sale.shipment_method = 'order'
+ sale.web_shop = self
+ sale.on_change_party()
+ sale.on_change_web_shop()
+ return sale
+
+
+class Shop_Warehouse(ModelSQL):
+ "Web Shop - Warehouse"
+ __name__ = 'web.shop-stock.location'
+
+ shop = fields.Many2One(
+ 'web.shop', "Shop", ondelete='CASCADE', required=True)
+ warehouse = fields.Many2One(
+ 'stock.location', "Warehouse", ondelete='CASCADE', required=True,
+ domain=[
+ ('type', '=', 'warehouse'),
+ ])
+
+
+class Shop_Product(Inactivate):
+ "Web Shop - Product"
+ __name__ = 'web.shop-product.product'
+
+ shop = fields.Many2One(
+ 'web.shop', "Shop", ondelete='CASCADE', required=True)
+ product = fields.Many2One(
+ 'product.product', "Product", ondelete='RESTRICT', required=True)
+
+
+class Shop_ProductCategory(Inactivate):
+ "Web Shop - Product Category"
+ __name__ = 'web.shop-product.category'
+
+ shop = fields.Many2One(
+ 'web.shop', "Shop", ondelete='CASCADE', required=True)
+ category = fields.Many2One(
+ 'product.category', "Category", ondelete='RESTRICT', required=True)
+
+
+class ShopAttribute(metaclass=PoolMeta):
+ __name__ = 'web.shop'
+
+ attributes = fields.Many2Many(
+ 'web.shop-product.attribute', 'shop', 'attribute', "Attributes",
+ help="The list of attributes to publish.")
+ attributes_removed = Many2ManyInactive(
+ 'web.shop-product.attribute', 'shop', 'attribute',
+ "Attributes Removed",
+ help="The list of attributes to unpublish.")
+
+ def get_attributes(self):
+ "Return the list of attributes"
+ pool = Pool()
+ Attribute = pool.get('product.attribute')
+ with Transaction().set_context(**self.get_context()):
+ return Attribute.browse(self.attributes)
+
+
+class Shop_Attribute(Inactivate):
+ "Web Shop - Attribute"
+ __name__ = 'web.shop-product.attribute'
+
+ shop = fields.Many2One(
+ 'web.shop', "Shop", ondelete='CASCADE', required=True)
+ attribute = fields.Many2One(
+ 'product.attribute', "Attribute", ondelete='RESTRICT', required=True)
+
+
+class User(metaclass=PoolMeta):
+ __name__ = 'web.user'
+
+ invoice_address = fields.Many2One(
+ 'party.address', "Invoice Address",
+ domain=['OR',
+ ('party', '=', Eval('party', -1)),
+ ('party', 'in', Eval('secondary_parties', [])),
+ ])
+ shipment_address = fields.Many2One(
+ 'party.address', "Shipment Address",
+ domain=['OR',
+ ('party', '=', Eval('party', -1)),
+ ('party', 'in', Eval('secondary_parties', [])),
+ ])
diff --git a/modules/web_shop/web.xml b/modules/web_shop/web.xml
new file mode 100644
index 0000000000..e765cabe76
--- /dev/null
+++ b/modules/web_shop/web.xml
@@ -0,0 +1,86 @@
+
+
+
+
+
+ web.shop
+ form
+ shop_form
+
+
+
+ web.shop
+ tree
+ shop_list
+
+
+
+ Web Shops
+ web.shop
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ User in companies
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ web.shop
+
+ shop_attribute_form
+
+
+
+
+
+ web.user
+
+ user_form
+
+
+
diff --git a/modules/web_shop_shopify/.drone.yml b/modules/web_shop_shopify/.drone.yml
new file mode 100644
index 0000000000..248cfe037b
--- /dev/null
+++ b/modules/web_shop_shopify/.drone.yml
@@ -0,0 +1,79 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ tox:
+ image: ${IMAGE}
+ environment:
+ - CFLAGS=-O0
+ - DB_CACHE=/cache
+ - TOX_TESTENV_PASSENV=CFLAGS DB_CACHE CI_BUILD_NUMBER CI_JOB_NUMBER CI_JOB_ID SHOPIFY_PASSWORD SHOPIFY_URL TRYTOND_WEB_SHOP_SHOPIFY__API_BACKOFF_TIME
+ - POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
+ secrets: [ shopify_password, shopify_url, trytond_web_shop_shopify__api_backoff_time ]
+ commands:
+ - echo "[extensions]" >> /root/.hgrc
+ - echo "hgext.share =" >> /root/.hgrc
+ - echo "[share]" >> /root/.hgrc
+ - echo "pool = /root/.cache/hg" >> /root/.hgrc
+ - pip install tox
+ - tox -e "${TOXENV}-${DATABASE}"
+ volumes:
+ - cache:/root/.cache
+ check_dist:
+ image: ${IMAGE}
+ commands:
+ - pip install twine
+ - python setup.py sdist
+ - twine check dist/*
+ volumes:
+ - cache:/root/.cache
+ check_doc:
+ image: ${IMAGE}
+ commands:
+ - pip install sphinx
+ - python -m sphinx -T -E -W -n -b html doc _build/html
+ - python -m sphinx -T -E -W -n -b linkcheck doc _build
+ volumes:
+ - cache:/root/.cache
+
+services:
+ postgresql:
+ image: postgres
+ environment:
+ - POSTGRES_HOST_AUTH_METHOD=trust
+ command: "-c fsync=off -c synchronous_commit=off -c full_page_writes=off"
+ when:
+ matrix:
+ DATABASE: postgresql
+
+matrix:
+ include:
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: sqlite
+ - IMAGE: python:3.7
+ TOXENV: py37
+ DATABASE: postgresql
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: sqlite
+ - IMAGE: python:3.8
+ TOXENV: py38
+ DATABASE: postgresql
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: sqlite
+ - IMAGE: python:3.9
+ TOXENV: py39
+ DATABASE: postgresql
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: sqlite
+ - IMAGE: python:3.10
+ TOXENV: py310
+ DATABASE: postgresql
diff --git a/modules/web_shop_shopify/.flake8 b/modules/web_shop_shopify/.flake8
new file mode 100644
index 0000000000..fa6b4f66d1
--- /dev/null
+++ b/modules/web_shop_shopify/.flake8
@@ -0,0 +1,2 @@
+[flake8]
+ignore=E123,E124,E126,E128,E741,W503
diff --git a/modules/web_shop_shopify/.isort.cfg b/modules/web_shop_shopify/.isort.cfg
new file mode 100644
index 0000000000..e1c6495da9
--- /dev/null
+++ b/modules/web_shop_shopify/.isort.cfg
@@ -0,0 +1,3 @@
+[settings]
+multi_line_output=4
+known_first_party=trytond
diff --git a/modules/web_shop_shopify/CHANGELOG b/modules/web_shop_shopify/CHANGELOG
new file mode 100644
index 0000000000..6d6e742b60
--- /dev/null
+++ b/modules/web_shop_shopify/CHANGELOG
@@ -0,0 +1,18 @@
+Version 6.6.0 - 2022-10-31
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Replace deprecated fulfillment by fulfillment order
+
+Version 6.4.0 - 2022-05-02
+--------------------------
+* Bug fixes (see mercurial logs for details)
+* Support webhook for orders
+* Remove API backoff time
+* Support edit orders from Shopify
+* Define the metafields managed by Tryton
+* Add support for Python 3.10
+* Remove support for Python 3.6
+
+Version 6.2.0 - 2021-11-01
+--------------------------
+* Initial release
diff --git a/modules/web_shop_shopify/COPYRIGHT b/modules/web_shop_shopify/COPYRIGHT
new file mode 100644
index 0000000000..852c531661
--- /dev/null
+++ b/modules/web_shop_shopify/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2021-2022 B2CK
+Copyright (C) 2021-2022 Cédric Krier
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/modules/web_shop_shopify/LICENSE b/modules/web_shop_shopify/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/modules/web_shop_shopify/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/modules/web_shop_shopify/MANIFEST.in b/modules/web_shop_shopify/MANIFEST.in
new file mode 100644
index 0000000000..f7e7aaa36b
--- /dev/null
+++ b/modules/web_shop_shopify/MANIFEST.in
@@ -0,0 +1,6 @@
+include CHANGELOG
+include COPYRIGHT
+include LICENSE
+include README.rst
+include icons/LICENSE
+graft doc
diff --git a/modules/web_shop_shopify/README.rst b/modules/web_shop_shopify/README.rst
new file mode 120000
index 0000000000..176d9c2695
--- /dev/null
+++ b/modules/web_shop_shopify/README.rst
@@ -0,0 +1 @@
+doc/index.rst
\ No newline at end of file
diff --git a/modules/web_shop_shopify/__init__.py b/modules/web_shop_shopify/__init__.py
new file mode 100644
index 0000000000..374f19ad1b
--- /dev/null
+++ b/modules/web_shop_shopify/__init__.py
@@ -0,0 +1,71 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+from trytond.pool import Pool
+
+from . import (
+ account, ir, party, product, routes, sale, shopify_retry, stock, web)
+
+__all__ = ['register', 'routes']
+
+shopify_retry.patch()
+
+
+def register():
+ Pool.register(
+ ir.Cron,
+ web.Shop,
+ web.ShopShopifyIdentifier,
+ web.Shop_Warehouse,
+ web.Shop_Attribute,
+ web.ShopShopifyPaymentJournal,
+ product.Category,
+ product.TemplateCategory,
+ product.Template,
+ product.Product,
+ product.ShopifyInventoryItem,
+ product.ProductIdentifier,
+ product.AttributeSet,
+ product.Attribute,
+ party.Party,
+ party.Address,
+ sale.Sale,
+ sale.Line,
+ account.Payment,
+ account.PaymentJournal,
+ stock.ShipmentOut,
+ stock.ShipmentShopifyIdentifier,
+ stock.Move,
+ module='web_shop_shopify', type_='model')
+ Pool.register(
+ product.ShopifyInventoryItem_Customs,
+ product.Product_TariffCode,
+ module='web_shop_shopify', type_='model', depends=['customs'])
+ Pool.register(
+ product.Image,
+ module='web_shop_shopify', type_='model', depends=['product_image'])
+ Pool.register(
+ product.Image_Attribute,
+ module='web_shop_shopify', type_='model',
+ depends=['product_attribute', 'product_image_attribute'])
+ Pool.register(
+ sale.Line_Discount,
+ module='web_shop_shopify', type_='model', depends=['sale_discount'])
+ Pool.register(
+ product.Template_SaleSecondaryUnit,
+ product.Product_SaleSecondaryUnit,
+ sale.Line_SaleSecondaryUnit,
+ module='web_shop_shopify', type_='model',
+ depends=['sale_secondary_unit'])
+ Pool.register(
+ sale.Sale_ShipmentCost,
+ sale.Line_ShipmentCost,
+ module='web_shop_shopify', type_='model',
+ depends=['sale_shipment_cost'])
+ Pool.register(
+ stock.ShipmentOut_PackageShipping,
+ module='web_shop_shopify', type_='model',
+ depends=['stock_package_shipping'])
+ Pool.register(
+ party.Replace,
+ module='web_shop_shopify', type_='wizard')
diff --git a/modules/web_shop_shopify/account.py b/modules/web_shop_shopify/account.py
new file mode 100644
index 0000000000..dccc87f599
--- /dev/null
+++ b/modules/web_shop_shopify/account.py
@@ -0,0 +1,135 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from collections import defaultdict
+from decimal import Decimal
+
+from trytond.model import Unique
+from trytond.pool import Pool, PoolMeta
+
+from .common import IdentifierMixin
+
+
+class Payment(IdentifierMixin, metaclass=PoolMeta):
+ __name__ = 'account.payment'
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ t = cls.__table__()
+ cls._sql_constraints += [
+ ('shopify_identifier_unique',
+ Unique(t, t.shopify_identifier_signed),
+ 'web_shop_shopify.msg_identifier_payment_unique'),
+ ]
+
+ @classmethod
+ def _get_shopify_payment_journal_pattern(cls, sale, transaction):
+ return {
+ 'gateway': transaction.gateway,
+ }
+
+ @classmethod
+ def _get_from_shopify(cls, sale, transaction):
+ assert transaction.kind in {'authorization', 'sale'}
+ payment = cls(shopify_identifier=transaction.id)
+ payment.company = sale.company
+ payment.journal = sale.web_shop.get_payment_journal(
+ transaction.currency,
+ cls._get_shopify_payment_journal_pattern(
+ sale, transaction))
+ payment.kind = 'receivable'
+ payment.amount = Decimal(transaction.amount)
+ payment.origin = sale
+ payment.party = sale.party
+ return payment
+
+ @classmethod
+ def get_from_shopify(cls, sale, order):
+ pool = Pool()
+ Group = pool.get('account.payment.group')
+
+ id2payments = {}
+ to_process = defaultdict(list)
+ transactions = [
+ t for t in order.transactions() if t.status == 'success']
+ # Order transactions to process parent first
+ kinds = ['authorization', 'capture', 'sale', 'void', 'refund']
+ transactions.sort(key=lambda t: kinds.index(t.kind))
+ amounts = defaultdict(Decimal)
+ for transaction in transactions:
+ if transaction.kind not in {'authorization', 'sale'}:
+ continue
+ payments = cls.search([
+ ('shopify_identifier', '=', transaction.id),
+ ])
+ if payments:
+ payment, = payments
+ else:
+ payment = cls._get_from_shopify(sale, transaction)
+ to_process[payment.company, payment.journal].append(payment)
+ id2payments[transaction.id] = payment
+ amounts[transaction.id] = Decimal(transaction.amount)
+ cls.save(list(id2payments.values()))
+
+ for (company, journal), payments in to_process.items():
+ group = Group(
+ company=company,
+ journal=journal,
+ kind='receivable')
+ group.save()
+ cls.submit(payments)
+ cls.process(payments, lambda: group)
+
+ captured = defaultdict(Decimal)
+ voided = defaultdict(Decimal)
+ refunded = defaultdict(Decimal)
+ for transaction in transactions:
+ if transaction.kind == 'sale':
+ payment = id2payments[transaction.id]
+ captured[payment] += Decimal(transaction.amount)
+ elif transaction.kind == 'capture':
+ payment = id2payments[transaction.parent_id]
+ id2payments[transaction.id] = payment
+ captured[payment] += Decimal(transaction.amount)
+ elif transaction.kind == 'void':
+ payment = id2payments[transaction.parent_id]
+ voided[payment] += Decimal(transaction.amount)
+ elif transaction.kind == 'refund':
+ payment = id2payments[transaction.parent_id]
+ captured[payment] -= Decimal(transaction.amount)
+ refunded[payment] += Decimal(transaction.amount)
+
+ to_save = []
+ for payment in id2payments.values():
+ if captured[payment] and payment.amount != captured[payment]:
+ payment.amount = captured[payment]
+ to_save.append(payment)
+ cls.proceed(to_save)
+ cls.save(to_save)
+
+ to_succeed, to_fail, to_proceed = set(), set(), set()
+ for transaction_id, payment in id2payments.items():
+ if amounts[transaction_id] == (
+ captured[payment] + voided[payment] + refunded[payment]):
+ if payment.amount:
+ if payment.state != 'succeeded':
+ to_succeed.add(payment)
+ else:
+ if payment.state != 'failed':
+ to_fail.add(payment)
+ elif payment.state != 'processing':
+ to_proceed.add(payment)
+ cls.fail(to_fail)
+ cls.proceed(to_proceed)
+ cls.succeed(to_succeed)
+
+ return list(id2payments.values())
+
+
+class PaymentJournal(metaclass=PoolMeta):
+ __name__ = 'account.payment.journal'
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls.process_method.selection.append(('shopify', "Shopify"))
diff --git a/modules/web_shop_shopify/common.py b/modules/web_shop_shopify/common.py
new file mode 100644
index 0000000000..f12575ee4c
--- /dev/null
+++ b/modules/web_shop_shopify/common.py
@@ -0,0 +1,161 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+from trytond.i18n import lazy_gettext
+from trytond.model import fields
+from trytond.pool import Pool
+
+
+class IdentifierMixin:
+ __slots__ = ()
+
+ shopify_identifier_signed = fields.BigInteger(
+ lazy_gettext('web_shop_shopify.msg_shopify_identifier'))
+ shopify_identifier = fields.Function(fields.BigInteger(
+ lazy_gettext('web_shop_shopify.msg_shopify_identifier')),
+ 'get_shopify_identifier', setter='set_shopify_identifier',
+ searcher='search_shopify_identifier')
+ shopify_identifier_char = fields.Function(fields.Char(
+ lazy_gettext('web_shop_shopify.msg_shopify_identifier')),
+ 'get_shopify_identifier', setter='set_shopify_identifier',
+ searcher='search_shopify_identifier')
+
+ def get_shopify_identifier(self, name):
+ if self.shopify_identifier_signed is not None:
+ value = self.shopify_identifier_signed + (1 << 63)
+ if name == 'shopify_identifier_char':
+ value = str(value)
+ return value
+
+ @classmethod
+ def set_shopify_identifier(cls, records, name, value):
+ cls.write(records, {
+ 'shopify_identifier_signed': int(value) - (1 << 63),
+ })
+
+ @classmethod
+ def search_shopify_identifier(cls, name, domain):
+ _, operator, value = domain
+ if operator in {'in', 'not in'}:
+ value = [
+ int(v) - (1 << 63) if v is not None else None for v in value]
+ elif value is not None:
+ value = int(value) - (1 << 63)
+ return [('shopify_identifier_signed', operator, value)]
+
+ @classmethod
+ def copy(cls, records, default=None):
+ if default is None:
+ default = {}
+ else:
+ default = default.copy()
+ default.setdefault('shopify_identifier_signed')
+ return super().copy(records, default=default)
+
+
+class IdentifiersUpdateMixin:
+ __slots__ = ()
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls._shopify_fields = set()
+
+ @classmethod
+ def set_shopify_to_update(cls, records):
+ pool = Pool()
+ Identifier = pool.get('web.shop.shopify_identifier')
+ identifiers = cls.get_shopify_identifier_to_update(records)
+ Identifier.write(identifiers, {
+ 'to_update': True,
+ })
+
+ @classmethod
+ def get_shopify_identifier_to_update(cls, records):
+ raise NotImplementedError
+
+ @classmethod
+ def write(cls, *args):
+ actions = iter(args)
+ to_update = set()
+ for records, values in zip(actions, actions):
+ if values.keys() & cls._shopify_fields:
+ to_update.update(records)
+ if to_update:
+ cls.set_shopify_to_update(cls.browse(list(to_update)))
+ super().write(*args)
+
+
+class IdentifiersMixin(IdentifiersUpdateMixin):
+ __slots__ = ()
+
+ shopify_identifiers = fields.One2Many(
+ 'web.shop.shopify_identifier', 'record',
+ lazy_gettext('web_shop_shopify.msg_shopify_identifiers'))
+
+ def get_shopify_identifier(self, web_shop):
+ for record in self.shopify_identifiers:
+ if record.web_shop == web_shop:
+ return record.shopify_identifier
+
+ def set_shopify_identifier(self, web_shop, identifier=None):
+ pool = Pool()
+ Identifier = pool.get('web.shop.shopify_identifier')
+ for record in self.shopify_identifiers:
+ if record.web_shop == web_shop:
+ if not identifier:
+ Identifier.delete([record])
+ return
+ else:
+ if record.shopify_identifier != identifier:
+ record.shopify_identifier = identifier
+ record.save()
+ return record
+ if identifier:
+ record = Identifier(record=self, web_shop=web_shop)
+ record.shopify_identifier = identifier
+ record.save()
+ return record
+
+ @classmethod
+ def search_shopify_identifier(cls, web_shop, identifier):
+ records = cls.search([
+ ('shopify_identifiers', 'where', [
+ ('web_shop', '=', web_shop.id),
+ ('shopify_identifier', '=', identifier),
+ ]),
+ ])
+ if records:
+ record, = records
+ return record
+
+ def is_shopify_to_update(self, web_shop, **extra):
+ for record in self.shopify_identifiers:
+ if record.web_shop == web_shop:
+ return (record.to_update
+ or (record.to_update_extra or {}) != extra)
+ return True
+
+ @classmethod
+ def copy(cls, records, default=None):
+ if default is None:
+ default = {}
+ else:
+ default = default.copy()
+ default.setdefault('shopify_identifiers')
+ return super().copy(records, default=default)
+
+ @classmethod
+ def delete(cls, records):
+ pool = Pool()
+ Identifier = pool.get('web.shop.shopify_identifier')
+ Identifier.delete(sum((r.shopify_identifiers for r in records), ()))
+ super().delete(records)
+
+ @classmethod
+ def get_shopify_identifier_to_update(cls, records):
+ return sum((list(r.shopify_identifiers) for r in records), [])
+
+
+def setattr_changed(record, name, value):
+ if getattr(record, name, None) != value:
+ setattr(record, name, value)
diff --git a/modules/web_shop_shopify/doc/conf.py b/modules/web_shop_shopify/doc/conf.py
new file mode 100644
index 0000000000..8513b72dd2
--- /dev/null
+++ b/modules/web_shop_shopify/doc/conf.py
@@ -0,0 +1,61 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+
+modules_url = 'https://docs.tryton.org/projects/modules-{module}/en/{series}/'
+trytond_url = 'https://docs.tryton.org/projects/server/en/{series}/'
+
+
+def get_info():
+ import configparser
+ import os
+ import subprocess
+ import sys
+
+ module_dir = os.path.dirname(os.path.dirname(__file__))
+
+ config = configparser.ConfigParser()
+ config.read_file(open(os.path.join(module_dir, 'tryton.cfg')))
+ info = dict(config.items('tryton'))
+
+ result = subprocess.run(
+ [sys.executable, 'setup.py', '--name'],
+ stdout=subprocess.PIPE, check=True, cwd=module_dir)
+ info['name'] = result.stdout.decode('utf-8').strip()
+
+ result = subprocess.run(
+ [sys.executable, 'setup.py', '--version'],
+ stdout=subprocess.PIPE, check=True, cwd=module_dir)
+ version = result.stdout.decode('utf-8').strip()
+ if 'dev' in version:
+ info['series'] = 'latest'
+ else:
+ info['series'] = '.'.join(version.split('.', 2)[:2])
+
+ for key in {'depends', 'extras_depend'}:
+ info[key] = info.get(key, '').strip().splitlines()
+ info['modules'] = set(info['depends'] + info['extras_depend'])
+ info['modules'] -= {'ir', 'res'}
+
+ return info
+
+
+info = get_info()
+
+master_doc = 'index'
+project = info['name']
+release = version = info['series']
+default_role = 'ref'
+highlight_language = 'none'
+extensions = [
+ 'sphinx.ext.intersphinx',
+ ]
+intersphinx_mapping = {
+ 'trytond': (trytond_url.format(series=version), None),
+ }
+intersphinx_mapping.update({
+ m: (modules_url.format(
+ module=m.replace('_', '-'), series=version), None)
+ for m in info['modules']
+ })
+
+del get_info, info, modules_url, trytond_url
diff --git a/modules/web_shop_shopify/doc/configuration.rst b/modules/web_shop_shopify/doc/configuration.rst
new file mode 100644
index 0000000000..73b1d329dd
--- /dev/null
+++ b/modules/web_shop_shopify/doc/configuration.rst
@@ -0,0 +1,17 @@
+*************
+Configuration
+*************
+
+The *Web Shop Shopify Module* uses values from settings in the
+``[web_shop_shopify]`` section of the :doc:`configuration file
+`.
+
+.. _config-web_shop_shopify.locations_cache:
+
+``locations_cache``
+====================
+
+The ``locations_cache`` defines the duration in seconds the Shopify locations
+are kept in the cache.
+
+The default value is: ``900`` (15 minutes)
diff --git a/modules/web_shop_shopify/doc/design.rst b/modules/web_shop_shopify/doc/design.rst
new file mode 100644
index 0000000000..06218fc64f
--- /dev/null
+++ b/modules/web_shop_shopify/doc/design.rst
@@ -0,0 +1,57 @@
+******
+Design
+******
+
+The *Web Shop Shopify Module* introduces some new concepts.
+
+.. _model-web.shop.shopify_identifier:
+
+Shopify Identifier
+==================
+
+A *Shopify Identifier* stores the Shopify ID for records from other models for
+each different :doc:`Web Shop `.
+
+.. seealso::
+
+ Identifiers are found by opening the main menu item:
+
+ |Administration --> Models --> Shopify Identifiers|__
+
+ .. |Administration --> Models --> Shopify Identifiers| replace:: :menuselection:`Administration --> Models --> Shopify Identifiers`
+ __ https://demo.tryton.org/model/web.shop.shopify_identifier
+
+.. _model-web.shop.shopify_payment_journal:
+
+Shopify Payment Journal
+=======================
+
+The *Shopify Payment Journal* stores the rules which are used to determine on
+which :doc:`Payment Journal ` the transactions are
+entered.
+
+.. _model-stock.shipment.shopify_identifier:
+
+Shopify Shipment Identifier
+===========================
+
+The *Shopify Shipment Identifier* concept stores the Shopify ID for the shipments
+for each `Sale `.
+
+.. seealso::
+
+ Identifiers are found by opening the main menu item:
+
+ |Administration --> Models --> Shopify Identifiers --> Shipment Identifiers|__
+
+ .. |Administration --> Models --> Shopify Identifiers --> Shipment Identifiers| replace:: :menuselection:`Administration --> Models --> Shopify Identifiers --> Shipment Identifiers`
+ __ https://demo.tryton.org/model/stock.shipment.shopify_identifier
+
+
+.. _model-web.shop.shopify_inventory_item:
+
+Shopify Inventory Item
+======================
+
+The *Shopify Inventory Item* concept manages the Shopify inventory item of each
+`Varient `.
diff --git a/modules/web_shop_shopify/doc/index.rst b/modules/web_shop_shopify/doc/index.rst
new file mode 100644
index 0000000000..26df1526ed
--- /dev/null
+++ b/modules/web_shop_shopify/doc/index.rst
@@ -0,0 +1,16 @@
+#######################
+Web Shop Shopify Module
+#######################
+
+The *Web Shop Shopify Module* provides a way to manage `Shopify
+`_ stores.
+It uploads products, variants and collections to Shopify, and downloads orders,
+transactions and creates fulfilments.
+
+.. toctree::
+ :maxdepth: 2
+
+ usage
+ configuration
+ design
+ releases
diff --git a/modules/web_shop_shopify/doc/releases.rst b/modules/web_shop_shopify/doc/releases.rst
new file mode 100644
index 0000000000..21b13c4745
--- /dev/null
+++ b/modules/web_shop_shopify/doc/releases.rst
@@ -0,0 +1,7 @@
+.. _releases-index:
+
+=============
+Release notes
+=============
+
+.. include:: ../CHANGELOG
diff --git a/modules/web_shop_shopify/doc/usage.rst b/modules/web_shop_shopify/doc/usage.rst
new file mode 100644
index 0000000000..5d186bd731
--- /dev/null
+++ b/modules/web_shop_shopify/doc/usage.rst
@@ -0,0 +1,43 @@
+*****
+Usage
+*****
+
+.. _Configure Shopify Web Shop:
+
+Configure Shopify Web Shop
+==========================
+
+First you must create a new `custom app
+`_ for your
+Shopify store with, as a minimum, the following permissions:
+
+ * Fulfillment services: Read and write
+
+ * Inventory: Read and write
+
+ * Orders: Read and write
+
+ * Product listings: Read and write
+
+ * Products: Read and write
+
+ * Assigned fulfillment: Read and write
+
+ * Merchant-managed fulfillment orders: Read and write
+
+You also need to copy the password that is generated.
+
+When setting the :doc:`Web Shop `'s type to "Shopify", you
+must fill in the "Shop URL" (e.g. ``https://