/** * 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'] ); } } } } } } } } Neo4j テーブル想定 – Raqqa

Neo4j テーブル想定

前提(命名ルール)

  • 追加DB(空DB)を kpi とし
  • スキーマは kg_poc を推奨
  • 企業差分を閉じ込めるため
    基本すべて company_key or company_id を持つ

1) 組織・原価センタ(企業差分の最重要)

目的Odoo拡張想定kpi DB 新規テーブル案
組織/拠点/部門辞書hr.department / res.company / (必要なら res.partnerkg_poc.org_unit
原価センタ辞書標準で専用テーブルが弱いので拡張で持つ想定kg_poc.cost_center
組織→原価センタhr.department に拡張フィールド or M2Mkg_poc.org_cost_center_map

kpi側の最小列イメージ

  • org_unit(org_key, name, parent_org_key, company_key, external_ref)
  • cost_center(cc_key, name, company_key, external_ref)
  • org_cost_center_map(org_key, cc_key, company_key)

2) 製品・品目・材料(材料ドライバの基盤)

目的Odoo拡張想定kpi DB 新規テーブル案
製品/品目マスタproduct_template, product_productkg_poc.product
材料辞書(カテゴリ含む)product_* を材料カテゴリで拡張kg_poc.material
製品→材料(BOM視点)mrp_bom, mrp_bom_linekg_poc.product_material_map

kpi側

  • product(product_key, name, category, company_key, external_ref)
  • material(material_key, name, category, uom, company_key, external_ref)
  • product_material_map(product_key, material_key, company_key, weight?)

3) 工程・ステップ・ルーティング(工程ドライバの基盤)

製造が絡む管理会計/RCAではここが核になります。

目的Odoo拡張想定kpi DB 新規テーブル案
工程辞書mrp.routing(バージョン差あり)/ mrp.workcenter と紐づけkg_poc.process
Step(工程の最小単位)Odoo標準では抽象度が高いので独自拡張kg_poc.step
Process→Stepルーティング拡張kg_poc.process_step_map
製品→Processmrp_routing*/BOM拡張kg_poc.product_process_map

kpi側

  • process(process_key, name, category, company_key, external_ref)
  • step(step_key, name, sequence, work_center_key?, company_key, external_ref)
  • process_step_map(process_key, step_key, company_key)
  • product_process_map(product_key, process_key, company_key)

4) スキル(説明要因)

目的Odoo拡張想定kpi DB 新規テーブル案
スキル辞書hr.skill(導入状況次第)/ hr.employee 拡張kg_poc.skill
Step→RequiredSkillルーティング/作業指示拡張kg_poc.step_required_skill
(任意)人/チームの保有スキルhr.employee 拡張kg_poc.actor_skill

kpi側

  • skill(skill_key, name, level_scale, company_key, external_ref)
  • step_required_skill(step_key, skill_key, required_level?, company_key)
  • actor_skill(actor_key, skill_key, actual_level?, company_key)
    ※ actor は人でもチームでもOK

5) 標準値(標準工数・標準使用量)

目的Odoo拡張想定kpi DB 新規テーブル案
標準工数mrp.workcenter/routing拡張kg_poc.standard_labor_time
標準使用量mrp_bom_line + 工程ひも付け拡張kg_poc.standard_material_qty

kpi側

  • standard_labor_time(step_key, std_minutes, valid_from?, valid_to?, company_key)
  • standard_material_qty(step_key, material_key, std_qty, uom, valid_from?, valid_to?, company_key)

6) 実績(販売・購買・在庫)

ここはOdoo参照で十分ですが、
PoCで“静的に作る”なら kpi 側に鏡を持ってもOK。

目的Odoo拡張想定kpi DB 新規テーブル案
販売実績sale_order, sale_order_linekg_poc.fact_sales
購買実績purchase_order, purchase_order_linekg_poc.fact_purchase
在庫実績stock_move, stock_quantkg_poc.fact_inventory

kpi側(任意)

  • fact_sales(doc_no, product_key, qty, price, amount, org_key?, period_key, company_key, source_ref)
  • fact_purchase(...)
  • fact_inventory(...)

Phase 1 は静的でもOKなので、
ここは“薄く”で大丈夫。


7) 会計(本番で会計が動く想定の受け皿)

あなたの方針どおり、

  • Odoo会計UIは今は触らない
  • でも 設計としては存在前提

なので、こう併記します。

目的Odoo拡張想定kpi DB 新規テーブル案
仕訳ヘッダaccount_movekg_poc.gl_entry
仕訳明細account_move_linekg_poc.gl_line
勘定科目account_accountkg_poc.gl_account

kpi側

  • gl_account(code, name, account_type, company_key, external_ref)
  • gl_entry(entry_key, entry_date, ref, company_key, source_ref)
  • gl_line(entry_key, account_code, debit, credit, memo?, company_key)

PoCはここを静的GLの正本として使うのが安全。


8) Phase 1 の“骨格テーブル”(KPI→Component→Driver)

ここがあなたの設計の中核。

目的Odoo拡張想定kpi DB 新規テーブル案
KPI定義Odoo標準に相当物なし(独自)kg_poc.kpi_def
Component定義Odoo標準に相当物なし(独自)kg_poc.component_def
KPI→Component独自kg_poc.kpi_component_map
Component→材料ドライバ独自kg_poc.component_material_driver_map
Component→工程ドライバ独自kg_poc.component_process_driver_map
KPI結果独自kg_poc.kpi_result
結果→根拠独自kg_poc.kpi_evidence_map

kpi側最小列

  • kpi_def(kpi_key, name, kpi_level, driver_type?, unit?, company_key)
  • component_def(component_key, component_type, name, company_key, external_ref?)
  • kpi_component_map(kpi_key, component_key, company_key)
  • component_material_driver_map(component_key, material_key or material_category, company_key, weight?)
  • component_process_driver_map(component_key, process_key or process_category, company_key, weight?)
  • kpi_result(company_key, period_key, kpi_key, value, calc_basis, notes?)
  • kpi_evidence_map(result_key or company+period+kpi, evidence_ref, company_key)

まとめ:Phase 1 で“現実の開発イメージが湧く”最小セット

Odoo拡張の影が濃い領域

  • 組織
  • 製品/材料
  • 工程/ステップ
  • スキル
  • 標準値
  • 実績(販売/購買/在庫)
  • 会計(将来)

PoCの骨格として必ず独自になる領域

  • KPI定義
  • Component
  • KPI→Component→Driver
  • KPI結果
  • Evidence

あなたの狙いに一番合う運用ルール

  • Odoo DB:参照専用
  • kpi DB:辞書/標準値/マッピング/静的GL/PoC結果の正本
  • Neo4j:kpi DB の派生

これで

「企業ごとの差分は辞書とマッピング」

RDB設計でも言い切れる状態になります。


Comments

コメントを残す

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