# This is an autogenerated file from the command "q2 generate_hq_api" and will be overwritten if run again
"""
DataSet models for UpdateCampaign.
These typed dataclass models represent the tables and columns within the
DataSet parameters for the UpdateCampaign HQ operation.
IMPORTANT: Update operations require a GET first to populate the original_record
field. HQ uses the unchanged row for optimistic concurrency checking.
Usage::
from q2_sdk.hq.hq_api.backoffice import UpdateCampaign
q2_marketing_message = UpdateCampaign.Q2MarketingMessage(
marketing_campaign_id=1,
description="...",
marketing_message_type_id=1,
)
q2v_marketing_ui_selection = UpdateCampaign.Q2vMarketingUiSelection(
)
q2_marketing_campaign = UpdateCampaign.Q2MarketingCampaign(
campaign_name="...",
start_date="...",
end_date="...",
enabled=True,
marketing_campaign_type_id=1,
)
q2v_marketing_campaign_target = UpdateCampaign.Q2vMarketingCampaignTarget(
marketing_campaign_id=1,
short_name="...",
description="...",
marketing_campaign_type_id=1,
marketing_campaign_type_short_name="...",
)
"""
from __future__ import annotations
import copy
from dataclasses import dataclass, field
from typing import Any, ClassVar, Optional
from q2_sdk.hq.models.dataset_builder import DataSetBuilder, DataSetTable, RowState
[docs]
@dataclass
class Q2MarketingMessage:
"""
Represents a row in the Q2_MarketingMessage table.
"""
marketing_message_id: int = -1
marketing_campaign_id: int = 0
payload: Optional[str] = None
target_url: Optional[str] = None
in_new_window: Optional[bool] = None
alignment: Optional[str] = None
content_type: Optional[str] = None
height: Optional[int] = None
width: Optional[int] = None
description: str = ""
marketing_message_type_id: int = 0
original_record: Optional["Q2MarketingMessage"] = field(default=None, repr=False)
[docs]
@staticmethod
def get_columns() -> list[list[str]]:
"""Returns [[HqColumnName, pythonAttrName], ...] mapping."""
return [
["MarketingMessageID", "marketing_message_id"],
["MarketingCampaignID", "marketing_campaign_id"],
["Payload", "payload"],
["TargetUrl", "target_url"],
["InNewWindow", "in_new_window"],
["Alignment", "alignment"],
["ContentType", "content_type"],
["Height", "height"],
["Width", "width"],
["Description", "description"],
["MarketingMessageTypeID", "marketing_message_type_id"],
]
[docs]
def to_row_values(self) -> list[Any]:
"""Returns column values in get_columns() order."""
return [
self.marketing_message_id,
self.marketing_campaign_id,
self.payload,
self.target_url,
self.in_new_window,
self.alignment,
self.content_type,
self.height,
self.width,
self.description,
self.marketing_message_type_id,
]
_COLUMN_TYPES: ClassVar[dict[str, type]] = {
"marketing_message_id": int,
"marketing_campaign_id": int,
"payload": str,
"target_url": str,
"in_new_window": bool,
"alignment": str,
"content_type": str,
"height": int,
"width": int,
"description": str,
"marketing_message_type_id": int,
}
[docs]
@classmethod
def from_hq_response(cls, row_elem) -> "Q2MarketingMessage":
"""Parse an lxml row element into this model with original_record set."""
kwargs: dict[str, Any] = {}
for hq_name, python_name in cls.get_columns():
child = row_elem.find(hq_name)
if child is not None and child.text is not None:
target_type = cls._COLUMN_TYPES.get(python_name, str)
if target_type is bool:
kwargs[python_name] = child.text.lower() in ("true", "1")
elif target_type in (int, float):
try:
kwargs[python_name] = target_type(child.text)
except (ValueError, TypeError):
kwargs[python_name] = child.text
else:
kwargs[python_name] = child.text
instance = cls(**kwargs)
instance.original_record = copy.deepcopy(instance)
return instance
[docs]
@dataclass
class Q2vMarketingUiSelection:
"""
Represents a row in the Q2_vMarketingUiSelection table.
"""
enabled: Optional[bool] = None
marketing_campaign_id: Optional[int] = None
ui_selection_id: Optional[int] = None
short_name: Optional[str] = None
description: Optional[str] = None
is_uux: Optional[bool] = None
marketing_campaign_type_id: Optional[int] = None
marketing_campaign_type_short_name: Optional[str] = None
original_record: Optional["Q2vMarketingUiSelection"] = field(
default=None, repr=False
)
[docs]
@staticmethod
def get_columns() -> list[list[str]]:
"""Returns [[HqColumnName, pythonAttrName], ...] mapping."""
return [
["Enabled", "enabled"],
["MarketingCampaignID", "marketing_campaign_id"],
["UiSelectionID", "ui_selection_id"],
["ShortName", "short_name"],
["Description", "description"],
["IsUux", "is_uux"],
["MarketingCampaignTypeID", "marketing_campaign_type_id"],
["MarketingCampaignTypeShortName", "marketing_campaign_type_short_name"],
]
[docs]
def to_row_values(self) -> list[Any]:
"""Returns column values in get_columns() order."""
return [
self.enabled,
self.marketing_campaign_id,
self.ui_selection_id,
self.short_name,
self.description,
self.is_uux,
self.marketing_campaign_type_id,
self.marketing_campaign_type_short_name,
]
_COLUMN_TYPES: ClassVar[dict[str, type]] = {
"enabled": bool,
"marketing_campaign_id": int,
"ui_selection_id": int,
"short_name": str,
"description": str,
"is_uux": bool,
"marketing_campaign_type_id": int,
"marketing_campaign_type_short_name": str,
}
[docs]
@classmethod
def from_hq_response(cls, row_elem) -> "Q2vMarketingUiSelection":
"""Parse an lxml row element into this model with original_record set."""
kwargs: dict[str, Any] = {}
for hq_name, python_name in cls.get_columns():
child = row_elem.find(hq_name)
if child is not None and child.text is not None:
target_type = cls._COLUMN_TYPES.get(python_name, str)
if target_type is bool:
kwargs[python_name] = child.text.lower() in ("true", "1")
elif target_type in (int, float):
try:
kwargs[python_name] = target_type(child.text)
except (ValueError, TypeError):
kwargs[python_name] = child.text
else:
kwargs[python_name] = child.text
instance = cls(**kwargs)
instance.original_record = copy.deepcopy(instance)
return instance
[docs]
@dataclass
class Q2MarketingCampaign:
"""
Represents a row in the Q2_MarketingCampaign table.
"""
marketing_campaign_id: int = -1
campaign_name: str = ""
start_date: str = ""
end_date: str = ""
enabled: bool = False
marketing_campaign_type_id: int = 0
zone_id: Optional[int] = None
original_record: Optional["Q2MarketingCampaign"] = field(default=None, repr=False)
[docs]
@staticmethod
def get_columns() -> list[list[str]]:
"""Returns [[HqColumnName, pythonAttrName], ...] mapping."""
return [
["MarketingCampaignID", "marketing_campaign_id"],
["CampaignName", "campaign_name"],
["StartDate", "start_date"],
["EndDate", "end_date"],
["Enabled", "enabled"],
["MarketingCampaignTypeID", "marketing_campaign_type_id"],
["ZoneID", "zone_id"],
]
[docs]
def to_row_values(self) -> list[Any]:
"""Returns column values in get_columns() order."""
return [
self.marketing_campaign_id,
self.campaign_name,
self.start_date,
self.end_date,
self.enabled,
self.marketing_campaign_type_id,
self.zone_id,
]
_COLUMN_TYPES: ClassVar[dict[str, type]] = {
"marketing_campaign_id": int,
"campaign_name": str,
"start_date": str,
"end_date": str,
"enabled": bool,
"marketing_campaign_type_id": int,
"zone_id": int,
}
[docs]
@classmethod
def from_hq_response(cls, row_elem) -> "Q2MarketingCampaign":
"""Parse an lxml row element into this model with original_record set."""
kwargs: dict[str, Any] = {}
for hq_name, python_name in cls.get_columns():
child = row_elem.find(hq_name)
if child is not None and child.text is not None:
target_type = cls._COLUMN_TYPES.get(python_name, str)
if target_type is bool:
kwargs[python_name] = child.text.lower() in ("true", "1")
elif target_type in (int, float):
try:
kwargs[python_name] = target_type(child.text)
except (ValueError, TypeError):
kwargs[python_name] = child.text
else:
kwargs[python_name] = child.text
instance = cls(**kwargs)
instance.original_record = copy.deepcopy(instance)
return instance
[docs]
@dataclass
class Q2vMarketingCampaignTarget:
"""
Represents a row in the Q2_vMarketingCampaignTarget table.
"""
enabled: Optional[bool] = None
marketing_campaign_id: int = 0
ui_page_name_id: Optional[int] = None
marketing_page_name_id: Optional[int] = None
short_name: str = ""
description: str = ""
marketing_campaign_type_id: int = 0
marketing_campaign_type_short_name: str = ""
original_record: Optional["Q2vMarketingCampaignTarget"] = field(
default=None, repr=False
)
[docs]
@staticmethod
def get_columns() -> list[list[str]]:
"""Returns [[HqColumnName, pythonAttrName], ...] mapping."""
return [
["Enabled", "enabled"],
["MarketingCampaignID", "marketing_campaign_id"],
["UiPageNameID", "ui_page_name_id"],
["MarketingPageNameID", "marketing_page_name_id"],
["ShortName", "short_name"],
["Description", "description"],
["MarketingCampaignTypeID", "marketing_campaign_type_id"],
["MarketingCampaignTypeShortName", "marketing_campaign_type_short_name"],
]
[docs]
def to_row_values(self) -> list[Any]:
"""Returns column values in get_columns() order."""
return [
self.enabled,
self.marketing_campaign_id,
self.ui_page_name_id,
self.marketing_page_name_id,
self.short_name,
self.description,
self.marketing_campaign_type_id,
self.marketing_campaign_type_short_name,
]
_COLUMN_TYPES: ClassVar[dict[str, type]] = {
"enabled": bool,
"marketing_campaign_id": int,
"ui_page_name_id": int,
"marketing_page_name_id": int,
"short_name": str,
"description": str,
"marketing_campaign_type_id": int,
"marketing_campaign_type_short_name": str,
}
[docs]
@classmethod
def from_hq_response(cls, row_elem) -> "Q2vMarketingCampaignTarget":
"""Parse an lxml row element into this model with original_record set."""
kwargs: dict[str, Any] = {}
for hq_name, python_name in cls.get_columns():
child = row_elem.find(hq_name)
if child is not None and child.text is not None:
target_type = cls._COLUMN_TYPES.get(python_name, str)
if target_type is bool:
kwargs[python_name] = child.text.lower() in ("true", "1")
elif target_type in (int, float):
try:
kwargs[python_name] = target_type(child.text)
except (ValueError, TypeError):
kwargs[python_name] = child.text
else:
kwargs[python_name] = child.text
instance = cls(**kwargs)
instance.original_record = copy.deepcopy(instance)
return instance
[docs]
def build_mcv_dataset(
q2_marketing_message: Optional[
Q2MarketingMessage | list[Q2MarketingMessage]
] = None,
q2v_marketing_ui_selection: Optional[
Q2vMarketingUiSelection | list[Q2vMarketingUiSelection]
] = None,
q2_marketing_campaign: Optional[
Q2MarketingCampaign | list[Q2MarketingCampaign]
] = None,
q2v_marketing_campaign_target: Optional[
Q2vMarketingCampaignTarget | list[Q2vMarketingCampaignTarget]
] = None,
) -> DataSetBuilder:
"""
Build the mcv DataSet parameter for UpdateCampaign.
For update operations, each model instance should have its original_record
set to the pre-modification state (from a prior GET call).
For add operations, set auto-increment ID fields to negative values.
:returns: DataSetBuilder ready to pass as the 'mcv' parameter
"""
dataset = DataSetBuilder("DalMarketingCampaignView")
# Q2_MarketingMessage
q2_marketing_message_cols = [col[0] for col in Q2MarketingMessage.get_columns()]
q2_marketing_message_table = dataset.add_table(
"Q2_MarketingMessage", q2_marketing_message_cols
)
_add_rows_to_table(q2_marketing_message_table, q2_marketing_message)
# Q2_vMarketingUiSelection
q2v_marketing_ui_selection_cols = [
col[0] for col in Q2vMarketingUiSelection.get_columns()
]
q2v_marketing_ui_selection_table = dataset.add_table(
"Q2_vMarketingUiSelection", q2v_marketing_ui_selection_cols
)
_add_rows_to_table(q2v_marketing_ui_selection_table, q2v_marketing_ui_selection)
# Q2_MarketingCampaign
q2_marketing_campaign_cols = [col[0] for col in Q2MarketingCampaign.get_columns()]
q2_marketing_campaign_table = dataset.add_table(
"Q2_MarketingCampaign", q2_marketing_campaign_cols
)
_add_rows_to_table(q2_marketing_campaign_table, q2_marketing_campaign)
# Q2_vMarketingCampaignTarget
q2v_marketing_campaign_target_cols = [
col[0] for col in Q2vMarketingCampaignTarget.get_columns()
]
q2v_marketing_campaign_target_table = dataset.add_table(
"Q2_vMarketingCampaignTarget", q2v_marketing_campaign_target_cols
)
_add_rows_to_table(
q2v_marketing_campaign_target_table, q2v_marketing_campaign_target
)
return dataset
def _add_rows_to_table(
table: DataSetTable,
records: Optional[Any | list],
) -> None:
"""
Add rows to a DataSetTable from one or more model instances.
Handles Modified+Unchanged pairs (for updates), Added rows (for inserts),
and Deleted rows automatically based on each record's original_record field.
"""
if records is None:
return
if not isinstance(records, list):
records = [records]
for record in records:
values = record.to_row_values()
if record.original_record is not None:
# Update: emit Modified row (new values) + Unchanged row (original)
table.add_row(RowState.MODIFIED, values)
table.add_row(RowState.UNCHANGED, record.original_record.to_row_values())
else:
# Add: emit Added row (new record)
table.add_row(RowState.ADDED, values)