from pathlib import Path from app.schema import DocumentProduct, CartOrderInfo, CartSessionItemOptions def typeset_flat_list(item_key: str, item_list: list[str | int]) -> str: """Convert flat list to string in the following format: => key: ["a", "b", 10, 44] """ flat_list = [] for s in item_list: flat_list.append(f'"{s}"') item = f" {item_key}: [{', '.join(flat_list)}]" return item def convert_pydantic_product_to_text(doc: DocumentProduct) -> str: """Convert a Pydantic model object (Product) into a text document ready to be written to disk. """ doc_dict = doc.model_dump() doc_dict_meta = doc_dict["meta"] # -- options options = [] if doc.meta.options: options.append("options:") if doc_dict_meta["options"]["size"]: size = typeset_flat_list("size", doc_dict_meta["options"]["size"]) else: size = " size: " if doc_dict_meta["options"]["style"]: style = typeset_flat_list("style", doc_dict_meta["options"]["style"]) else: style = " style: " options.append(size) options.append(style) if len(options): options = "\n".join(options) # -- inventory inventory = ["inventory:"] for item in doc_dict_meta["inventory"]: unit = [] if item["product_variation_id"]: unit.append(f" - product_variation_id: \"{item['product_variation_id']}\"") else: unit.append(" - product_variation_id:") if item["size"]: unit.append(f" size: \"{item['size']}\"") else: unit.append(" size:") if item["style"]: unit.append(f" style: \"{item['style']}\"") else: unit.append(" style:") unit.append(f" amount: {item['amount']}") unit = "\n".join(unit) inventory.append(unit) inventory = "\n".join(inventory) # -- assemble txt_meta txt_meta = ( "---", f"type: \"{doc_dict_meta['type']}\"", f"title: \"{doc_dict_meta['title']}\"", f"template: \"{doc_dict_meta['template']}\"", f"code: \"{doc_dict_meta['code']}\"", f"product_id: \"{doc_dict_meta['product_id']}\"", f"price: {doc_dict_meta['price']}", f"weight: {doc_dict_meta['weight']}", f"customs_tariff_code: \"{doc_dict_meta['customs_tariff_code']}\"", f"origin_country_iso: \"{doc_dict_meta['origin_country_iso']}\"", f"category: \"{doc_dict_meta['category']}\"", ) if len(options): txt_meta = txt_meta + (f"{options}",) txt_meta = txt_meta + (f"{inventory}",) # -- txt_blocks = [] for block in doc_dict["blocks"]: if block["type"] == "text": txt_blocks.append(block["value"]) elif block["type"] == "image": caption = "" if block["caption"]: caption = f"caption: \"{block['caption']}\"" url_p = Path(block["url"]) url = f"{url_p.stem}{url_p.suffix}" block_img = ( f"type: \"{block['type']}\"", f'url: "{url}"', f"{caption}", ) block_img = "\n".join(block_img) txt_blocks.append(block_img) txt_meta = "\n".join(txt_meta) txt_blocks = "\n---\n".join(txt_blocks) txt_doc = "\n---\n".join((txt_meta, txt_blocks)) txt_doc = f"{txt_doc}\n" return txt_doc def format_yaml_multiline(text: str, indent: bool = False) -> str: """ Manually indent multiline values for YAML key. """ lines = text.splitlines() if indent: lines = [f"{line.rjust(len(line) +4)}" for line in lines] lines = "\n".join(lines) return lines def typeset_order_content( items_table, currency: str, subtotal: int, shipping: int, total: int ) -> str: """Return a multiline string of the orders' content (list of product items, price, etc.). Useful for when sending out an email. """ content_order_txt = [] for i in items_table: item_txt = f"- {i.quantity}x {i.title}, {currency} {i.price}\n" content_order_txt.append(item_txt) subtotal_txt = f"\nSubtotal {currency} {subtotal}\n" shipping_txt = f"Shipping {currency} {shipping}\n" total_txt = f"Total {currency} {total}" content_order_txt.append(subtotal_txt) content_order_txt.append(shipping_txt) content_order_txt.append(total_txt) return "".join(content_order_txt) def typeset_order_shipping_info(shipping_info): """Return a multiline string of the shipping info, useful for when sending out an email. """ shipping_info_txt = [] if shipping_info.first_name: shipping_info_txt.append( f"{shipping_info.first_name} {shipping_info.last_name}\n" ) else: shipping_info_txt.append(f"{shipping_info.last_name}\n") address_full = f"{shipping_info.address}, {shipping_info.address_no}" shipping_info_txt.append(f"{address_full}\n") if shipping_info.address_extra: shipping_info_txt.append(f"{shipping_info.address_extra}\n") shipping_info_txt.append(f"{shipping_info.postal_code} {shipping_info.city}\n") shipping_info_txt.append(f"{shipping_info.country}") if shipping_info.phone_number: shipping_info_txt.append(f"{shipping_info.phone_number}") if shipping_info.note: note = format_yaml_multiline(shipping_info.note) shipping_info_txt.append(f"\n\n{note}") shipping_info_txt = "".join(shipping_info_txt) return shipping_info_txt def format_order_items(items: list[CartOrderInfo | dict[str, str | int]]) -> str: """ """ items_table = [] for i in items: if type(i) is dict: i['options'] = CartSessionItemOptions(size=None, style=None) i = CartOrderInfo(**i) item_title = i.title if i.options.style: item_title += f" - {i.options.style.capitalize()}" if i.options.size: item_title += f" Size {i.options.size.upper()}" item = ( f" - code: '{i.code}'\n" f" title: '{item_title}'\n" f" quantity: '{i.quantity}'\n" f" price: '{i.price}'\n" ) items_table.append(item) items_table = "".join(items_table) return items_table def format_order_shipping_info(shipping_info) -> str: """ """ note = "" if shipping_info.note: note = f"|\n{format_yaml_multiline(shipping_info.note, indent=True)}" shipping_info_table = ( f" first_name: '{shipping_info.first_name or ''}'\n" f" last_name: '{shipping_info.last_name}'\n" f" address: '{shipping_info.address}'\n" f" address_no: '{shipping_info.address_no}'\n" f" address_extra: '{shipping_info.address_extra or ''}'\n" f" postal_code: '{shipping_info.postal_code}'\n" f" city: '{shipping_info.city}'\n" f" country: '{shipping_info.country}'\n" f" note: '{note}'\n" f" email: '{shipping_info.email}'\n" f" phone_number: '{shipping_info.phone_number or ''}'\n" ) return shipping_info_table