/** * 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 ポータルサイト – Raqqa

Odoo ポータルサイト

TOP画面のER図

erDiagram

devp_model {
  BIGSERIAL id PK
  TEXT  module_name
  TEXT  model_name
  TEXT  display_name
  TEXT  table_name
  TEXT  business_domain
  TEXT  category
  TEXT  customization_status
  TEXT  lifecycle_status
  TEXT  origin
  TEXT  codegen_status
  TEXT  owner
  TEXT  tags
  TEXT  customization_summary
  TEXT  odoo_screen_url
  TIMESTAMPTZ last_updated_at
  TIMESTAMPTZ created_at
  TIMESTAMPTZ updated_at
}

devp_field {
  BIGSERIAL id PK
  BIGINT model_id FK
  TEXT field_name
}

devp_view_hdr {
  BIGSERIAL id PK
  BIGINT model_id FK
  TEXT view_name
  TEXT view_type
}

devp_tab_hdr {
  BIGSERIAL id PK
  BIGINT model_id FK
  TEXT tab_name
  TEXT child_model
}

devp_smart_button {
  BIGSERIAL id PK
  BIGINT model_id FK
  TEXT button_name
}

devp_menu {
  BIGSERIAL id PK
  BIGINT model_id FK
  TEXT menu_path
  TEXT action_external_id
}

devp_relation {
  BIGSERIAL id PK
  BIGINT model_id FK
  TEXT relation_type
  TEXT local_field
  TEXT related_model
}

devp_automation {
  BIGSERIAL id PK
  BIGINT model_id FK
  TEXT trigger
  TEXT action_type
}

devp_code_link {
  BIGSERIAL id PK
  BIGINT model_id FK
  TEXT entity_type
  BIGINT entity_ref_id
}

devp_model_summary {
  BIGINT model_id PK
  TEXT  module_name
  TEXT  model_name
  TEXT  display_name
  TEXT  table_name
  TEXT  business_domain
  TEXT  lifecycle_status
  TEXT  customization_status
  TEXT  customization_summary
  TEXT  origin
  TEXT  owner
  TEXT  tags
  TIMESTAMPTZ last_updated_at
  INT   fields_count
  INT   views_count
  INT   tabs_count
  INT   buttons_count
  INT   menus_count
  INT   relations_count
  INT   automations_count
  INT   code_links_count
  TEXT  odoo_screen_url
}

devp_model ||--o{ devp_field        : has
devp_model ||--o{ devp_view_hdr     : has
devp_model ||--o{ devp_tab_hdr      : has
devp_model ||--o{ devp_smart_button : has
devp_model ||--o{ devp_menu         : has
devp_model ||--o{ devp_relation     : has
devp_model ||--o{ devp_automation   : has
devp_model ||--o{ devp_code_link    : has
devp_model ||--o| devp_model_summary: summarized_by

モデルの詳細ER図

erDiagram

%% ================= CORE (Model Basic) =================
devp_model {
  BIGSERIAL id PK
  TEXT      module_name         "使用モジュール (例: sale_management)"
  TEXT      model_name          "内部名 (例: sale.order)"
  TEXT      display_name        "表示名 (例: 販売注文)"
  TEXT      description         "説明 (業務用途の概要)"
  TEXT      customization_status "カスタマイズ状況 (例: 基本構成のまま)"
  TEXT      category            "任意: マスタ/トランザクション 等"
  TEXT      origin              "Studio|Code|Both|Mixed"
  TIMESTAMPTZ created_at
  TIMESTAMPTZ updated_at
}

%% ================= Fields =================
devp_field {
  BIGSERIAL id PK
  BIGINT   model_id FK
  TEXT     field_name           "内部名 (例: x_customer_grade)"
  TEXT     label_ja             "日本語ラベル (例: グレード)"
  TEXT     label_en             "英語ラベル(任意)"
  TEXT     field_type           "selection|float|..."
  TEXT     origin               "Studio|Code|Both"
  TEXT     codegen_status       "生成済|手動修正要 など"
  BOOLEAN  required
  TEXT     widget_hint          "表示意図(任意)"
  TEXT     description          "説明(任意)"
}

%% ================= Views =================
devp_view {
  BIGSERIAL id PK
  BIGINT   model_id FK
  TEXT     view_name            "例: 見積入力フォーム"
  TEXT     view_type            "Form|List|Search|..."
  TEXT     origin               "Studio|Code|Both"
  BOOLEAN  codegen
  TEXT     note                 "備考(任意)"
}

%% ================= Tabs (Header + Detail) =================
devp_tab_hdr {
  BIGSERIAL id PK
  BIGINT   model_id FK
  TEXT     tab_name             "例: 見積明細/添付ファイル履歴/配送追跡"
  TEXT     child_model          "例: sale.order.line / ir.attachment / stock.move"
  TEXT     origin               "Studio|Code|Mixed|Both"
  BOOLEAN  codegen
  TEXT     note                 "用途/要約 (例: 注文行のOne2many, 在庫移動の詳細追跡)"
}

devp_tab_detail {
  BIGSERIAL id PK
  BIGINT   tab_id FK
  TEXT     link_m2o             "子→親のM2O (例: order_id)"
  TEXT     subview_mode         "例: tree,form"
  TEXT     subview_tree_id      "例: sale_order_line_tree"
  TEXT     subview_form_id      "例: sale_order_line_form"
  TEXT     domain_expr          "例: [('state','!=','cancel')]"
  TEXT     context_expr         "例: {'default_order_id': active_id}"
  TEXT     editable_opts        "例: editable='bottom'"
  TEXT     options_json         "例: {'no_create': False, 'no_delete': False}"
  TEXT     detail_note          "技術的説明/メモ(任意)"
}

%% ================= Smart Buttons =================
devp_smart_button {
  BIGSERIAL id PK
  BIGINT   model_id FK
  TEXT     button_name
  TEXT     target_model
  TEXT     origin               "Studio|Code|Both"
  BOOLEAN  show_counter
  TEXT     target_url
  BOOLEAN  codegen
  TEXT     note
}

%% ================= Menus =================
devp_menu {
  BIGSERIAL id PK
  BIGINT   model_id FK
  TEXT     menu_path            "Sales › Orders 等"
  SMALLINT indent               "0,1,2..."
  TEXT     action_external_id   "例: sale.action_orders"
  TEXT     target_model         "例: sale.order"
  TEXT[]   view_modes           "{'kanban','tree','form','pivot','graph',...}"
  TEXT     initial_domain       "初期ドメイン式"
  TEXT     origin               "Studio|Code|Mixed"
  BOOLEAN  has_code             "コード参照の有無"
}

%% ================= Relations (一次連結) =================
devp_relation {
  BIGSERIAL id PK
  BIGINT   model_id FK
  TEXT     relation_type        "M2O|O2M|M2M"
  TEXT     local_field          "こちらのフィールド (例: partner_id, order_line)"
  TEXT     related_model        "相手モデル (例: res.partner)"
  TEXT     related_key          "相手側キー/結合軸 (例: id, order_id, invoice_origin)"
  TEXT     inverse_field        "逆参照 (子側のM2O名 等)"
  TEXT     via_table            "M2M中間テーブル (例: mail_followers)"
  TEXT     via_local_key        "中間テーブルのこちら側キー"
  TEXT     via_remote_key       "中間テーブルの相手側キー"
  TEXT     res_model_filter     "例: 'sale.order' (M2M制約)"
  TEXT     purpose_summary      "用途/要約"
  TEXT     sql_join_hint        "JOINヒント (自由記述)"
  TEXT     origin               "Studio|Code|Both|Mixed"
}

%% ================= Code Links (Polymorphic) =================
devp_code_link {
  BIGSERIAL id PK
  BIGINT   model_id FK
  TEXT     entity_type          "menu|field|view|tab_hdr|tab_detail|button|automation|model|relation"
  BIGINT   entity_ref_id        "対象行ID"
  TEXT     repo                 "org/repo"
  TEXT     branch               "main|feature/..."
  TEXT[]   paths                "関連ファイルパス"
  TEXT     commit_sha
  INT      pr_number
  TEXT     env_status           "dev|stg|prod (任意)"
}

%% ================= Relationships =================
devp_model ||--o{ devp_field        : has
devp_model ||--o{ devp_view         : has
devp_model ||--o{ devp_tab_hdr      : has
devp_tab_hdr ||--o{ devp_tab_detail : details
devp_model ||--o{ devp_smart_button : has
devp_model ||--o{ devp_menu         : has
devp_model ||--o{ devp_relation     : has
devp_model ||--o{ devp_code_link    : links

devp_menu        ||--o{ devp_code_link : "entity_type='menu'"
devp_field       ||--o{ devp_code_link : "entity_type='field'"
devp_view        ||--o{ devp_code_link : "entity_type='view'"
devp_tab_hdr     ||--o{ devp_code_link : "entity_type='tab_hdr'"
devp_tab_detail  ||--o{ devp_code_link : "entity_type='tab_detail'"
devp_smart_button||--o{ devp_code_link : "entity_type='button'"
devp_relation    ||--o{ devp_code_link : "entity_type='relation'"

フィールド詳細

erDiagram

devp_model {
  int id
  string model_name
  string display_name
}

devp_field {
  int id
  int model_id
  string field_name
  string label
  string field_type
  string impl_style
  datetime updated_at
}

devp_field_studio {
  int id
  int field_id
  string widget
  boolean required
  string help_text
  string placeholder
  string visible_condition_expr
  string readonly_condition_expr
  boolean layout_inline_horizontal
  string groups_xml_ids
}

devp_field_adv {
  int id
  int field_id
  string note
  datetime updated_at
}

devp_field_adv_condition {
  int id
  int field_id
  string invisible_expr
  string required_expr
  string readonly_expr
  string when_view_type
}

devp_field_compute {
  int id
  int field_id
  boolean is_computed
  string compute_method
  string inverse_method
  string search_method
  string depends_list
  boolean store
}

devp_field_onchange {
  int id
  int field_id
  string method_ref
  string trigger_fields
  string description
}

devp_field_domain_rule {
  int id
  int field_id
  string use_case
  string domain_expr
  string condition_expr
}

devp_field_validation {
  int id
  int field_id
  string kind
  string name
  string expression_or_sql
  string message
}

devp_field_context_rule {
  int id
  int field_id
  string use_case
  string context_json
  string condition_expr
}

devp_field_security_rule {
  int id
  int field_id
  string groups_xml_ids
  string visible_condition
  string editable_condition
}

devp_field_widget_custom {
  int id
  int field_id
  string widget_name
  string props_json
  string assets_path
  string description
}

devp_field_ai {
  int id
  int field_id
  string prompt_text
  string gen_python
  string gen_xml
  string gen_security
  string status
  datetime generated_at
}

devp_field_file {
  int id
  int field_id
  string file_kind
  string file_name
  string storage_path
  datetime added_at
}

devp_manifest_snapshot {
  int id
  int field_id
  string module_name
  string manifest_text
  datetime captured_at
}

devp_model ||--o{ devp_field : has
devp_field ||--o| devp_field_studio : studio
devp_field ||--o| devp_field_adv : advanced
devp_field ||--o{ devp_field_adv_condition : adv_cond
devp_field ||--o| devp_field_compute : compute
devp_field ||--o{ devp_field_onchange : onchange
devp_field ||--o{ devp_field_domain_rule : domain
devp_field ||--o{ devp_field_validation : validate
devp_field ||--o{ devp_field_context_rule : context
devp_field ||--o{ devp_field_security_rule : security
devp_field ||--o| devp_field_widget_custom : widget
devp_field ||--o| devp_field_ai : ai
devp_field ||--o{ devp_field_file : files
devp_field ||--o| devp_manifest_snapshot : manifest

Comments

コメントを残す

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