/** * WPML compatibility functions * * @global array $duplicated_posts Array to store the posts being duplicated. * * @package Yoast\WP\Duplicate_Post * @since 3.2 */ add_action( 'admin_init', 'duplicate_post_wpml_init' ); /** * Add handlers for WPML compatibility. */ function duplicate_post_wpml_init() { if ( defined( 'ICL_SITEPRESS_VERSION' ) ) { add_action( 'dp_duplicate_page', 'duplicate_post_wpml_copy_translations', 10, 3 ); add_action( 'dp_duplicate_post', 'duplicate_post_wpml_copy_translations', 10, 3 ); add_action( 'shutdown', 'duplicate_wpml_string_packages', 11 ); } } global $duplicated_posts; // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: Renaming a global variable is a BC break. $duplicated_posts = []; /** * Copy post translations. * * @global SitePress $sitepress Instance of the Main WPML class. * @global array $duplicated_posts Array of duplicated posts. * * @param int $post_id ID of the copy. * @param WP_Post $post Original post object. * @param string $status Status of the new post. */ function duplicate_post_wpml_copy_translations( $post_id, $post, $status = '' ) { global $sitepress; global $duplicated_posts; remove_action( 'dp_duplicate_page', 'duplicate_post_wpml_copy_translations', 10 ); remove_action( 'dp_duplicate_post', 'duplicate_post_wpml_copy_translations', 10 ); $current_language = $sitepress->get_current_language(); $trid = $sitepress->get_element_trid( $post->ID ); if ( ! empty( $trid ) ) { $translations = $sitepress->get_element_translations( $trid ); $new_trid = $sitepress->get_element_trid( $post_id ); foreach ( $translations as $code => $details ) { if ( $code !== $current_language ) { if ( $details->element_id ) { $translation = get_post( $details->element_id ); if ( ! $translation ) { continue; } $new_post_id = duplicate_post_create_duplicate( $translation, $status ); if ( ! is_wp_error( $new_post_id ) ) { $sitepress->set_element_language_details( $new_post_id, 'post_' . $translation->post_type, $new_trid, $code, $current_language ); } } } } // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: see above. $duplicated_posts[ $post->ID ] = $post_id; } } /** * Duplicate string packages. * * @global array() $duplicated_posts Array of duplicated posts. */ function duplicate_wpml_string_packages() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: renaming the function would be a BC-break. global $duplicated_posts; foreach ( $duplicated_posts as $original_post_id => $duplicate_post_id ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter. $original_string_packages = apply_filters( 'wpml_st_get_post_string_packages', false, $original_post_id ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter. $new_string_packages = apply_filters( 'wpml_st_get_post_string_packages', false, $duplicate_post_id ); if ( is_array( $original_string_packages ) ) { foreach ( $original_string_packages as $original_string_package ) { $translated_original_strings = $original_string_package->get_translated_strings( [] ); foreach ( $new_string_packages as $new_string_package ) { $cache = new WPML_WP_Cache( 'WPML_Package' ); $cache->flush_group_cache(); $new_strings = $new_string_package->get_package_strings(); foreach ( $new_strings as $new_string ) { if ( isset( $translated_original_strings[ $new_string->name ] ) ) { foreach ( $translated_original_strings[ $new_string->name ] as $language => $translated_string ) { do_action( // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter. 'wpml_add_string_translation', $new_string->id, $language, $translated_string['value'], $translated_string['status'] ); } } } } } } } } Odoo サブアセンブリ MRP – Raqqa

Odoo サブアセンブリ MRP

🏗 Sub-Assemblies(サブアセンブリ)とは?

サブアセンブリとは、**最終製品の構成部品として別途製造される中間製品(部品の部品)**のことです。

例:
「完成品A」 = 「組立部品B(サブアセンブリ)」 + 「部品C」

🚲 Odoo MRPにおける Sub-Assemblies(サブアセンブリ)の構成と運用

🎯 想定例:自転車(完成品)の一部として「ハンドル」(サブアセンブリ)を組み立てるケース


🧱 製品構成(BOMの階層)

▸ 完成品:自転車(製品A)

  • ハンドル(製品B:サブアセンブリ)
  • フレーム
  • タイヤ

▸ サブアセンブリ:ハンドル(製品B)

  • ライト(購買品)
  • グリップ(在庫品)
  • バー(在庫品)

🛠 ステップ1:各製品のBOMとルート設定

ライト

  • BOM:なし(購入品)
  • ルート:✅ BUY(購買)

グリップ / バー

  • BOM:なし(在庫品)
  • ルート:通常の在庫品として登録(BUYも可)

ハンドル(サブアセンブリ)

  • BOM:ライト + グリップ + バー
  • ルート:✅ Manufacture(製造)

自転車(完成品)

  • BOM:ハンドル + フレーム + タイヤ
  • ルート:✅ Manufacture(製造)

🏭 ステップ2:製造オーダー(MO)の作成と自動分割

  1. 自転車(製品A)の 製造オーダー(MO)を作成
  2. Odooは、BOM内の「ハンドル(製品B)」が**製造ルート(Manufacture)**になっていることを検出
  3. ハンドル用の子製造オーダー(Child MO) が自動生成される
    • MO画面に「Child MO(スマートボタン)」が表示され、クリックで確認可能
  4. ハンドルMOでは、ライトは購買オーダー(PO)が自動生成される

🔄 ステップ3:製造順序と処理

順番操作補足
1ハンドル(Child MO)の製造開始構成品のうち、ライトは購入が必要(PO作成)
2ライトの受領処理(Receive Products)購買ルートに基づいて在庫に補充
3ハンドルMOを完了ハンドルが在庫に入る
4自転車(親MO)の製造が可能にハンドルがAvailableになる
5自転車MOを完了製品完成・出荷可能

✅ まとめ:ポイント整理

項目内容
サブアセンブリの定義ハンドルのようにBOMを持つ部品は、製造ルートとして扱う
Child MOの自動生成親のMOから製造ルートを持つ部品が検出されると、自動でMOが生成される
購買品の処理BOM内の部品が「BUY」ルートを持つと、MOではなくPOが生成される
製造順序Child MOを先に処理し、親MOに部品を供給してから本製造を行う必要がある


Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です