Esempio n. 1
0
def main():
    """main"""
    default_config = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                  "cctools.cfg")
    now = datetime.datetime.now()
    default_xlsx_filename = now.strftime("%Y-%m-%d-PurchaseOrder.xlsx")

    arg_parser = argparse.ArgumentParser(
        description="Generates a FedEx Product Dictionary.")
    arg_parser.add_argument(
        "--config",
        action="store",
        dest="config",
        metavar="FILE",
        default=default_config,
        help="configuration filename (default=%(default)s)")
    arg_parser.add_argument("--outfile",
                            action="store",
                            dest="xlsx_filename",
                            metavar="FILE",
                            default=default_xlsx_filename,
                            help="output XLSX filename (default=%(default)s)")
    arg_parser.add_argument("--exclude-sku",
                            action="append",
                            dest="exclude_skus",
                            metavar="SKU",
                            help="exclude SKU from output")
    arg_parser.add_argument("--verbose",
                            action="store_true",
                            default=False,
                            help="display progress messages")

    # Parse command line arguments.
    args = arg_parser.parse_args()

    # Configure logging.
    logging.basicConfig(
        level=logging.INFO if args.verbose else logging.WARNING)
    logger = logging.getLogger()

    # Also log using notify-send if it is available.
    if notify_send_handler.NotifySendHandler.is_available():
        logger.addHandler(
            notify_send_handler.NotifySendHandler(
                os.path.splitext(os.path.basename(__file__))[0]))

    # Read config file.
    config = ConfigParser.RawConfigParser()
    config.readfp(open(args.config))

    # Create a connection to CoreCommerce.
    cc_browser = cctools.CCBrowser(config.get("website", "base_url"),
                                   config.get("website", "username"),
                                   config.get("website", "password"))

    # Fetch products list.
    products = cc_browser.get_products()

    # Generate spreadsheet.
    logger.debug("Generating {}".format(os.path.abspath(args.xlsx_filename)))
    generate_xlsx(args, cc_browser, products)

    logger.debug("Generation complete")
    return 0
Esempio n. 2
0
def main():
    """main"""
    # Construct default filename of configuration file.
    default_config = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                  "cctools.cfg")
    now = datetime.datetime.now()
    default_pdf_filename = now.strftime("%Y-%m-%d-WholesaleOrderForm.pdf")

    arg_parser = argparse.ArgumentParser(
        description=("Generates a printable wholesale order form "
                     "from CoreCommerce data."))
    arg_parser.add_argument(
        "--config",
        metavar="FILE",
        default=default_config,
        help="configuration filename (default=%(default)s)")
    arg_parser.add_argument("--category",
                            action="append",
                            dest="categories",
                            metavar="CAT",
                            help="include category in output")
    arg_parser.add_argument("--exclude-category",
                            action="append",
                            dest="exclude_categories",
                            metavar="CAT",
                            help="exclude category from output")
    arg_parser.add_argument("--exclude-sku",
                            action="append",
                            dest="exclude_skus",
                            metavar="SKU",
                            help="exclude SKU from output")
    arg_parser.add_argument("--pdf-file",
                            metavar="FILE",
                            default=default_pdf_filename,
                            help="output PDF filename (default=%(default)s)")
    arg_parser.add_argument("--add-sku",
                            dest="add_sku",
                            action="store_true",
                            default=False,
                            help="append SKU to product name")
    arg_parser.add_argument("--ncols",
                            type=int,
                            metavar="N",
                            default=2,
                            help="number of report columns (default=2)")
    arg_parser.add_argument("--greybar-interval",
                            type=int,
                            metavar="N",
                            default=2,
                            help="greybar interval (default=%(default)i)")
    arg_parser.add_argument(
        "--wholesale-fraction",
        metavar="FRAC",
        default=0.5,
        help="wholesale price fraction (default=%(default).2f)")
    arg_parser.add_argument("--verbose",
                            action="store_true",
                            default=False,
                            help="display progress messages")

    # Parse command line arguments.
    args = arg_parser.parse_args()
    if args.categories and args.exclude_categories:
        arg_parser.error("--category and --exclude-category specified")

    # Configure logging.
    logging.basicConfig(
        level=logging.INFO if args.verbose else logging.WARNING)
    logger = logging.getLogger()

    # Also log using notify-send if it is available.
    if notify_send_handler.NotifySendHandler.is_available():
        logger.addHandler(
            notify_send_handler.NotifySendHandler(
                os.path.splitext(os.path.basename(__file__))[0]))

    # Read config file.
    config = ConfigParser.SafeConfigParser({
        "body_fontsize": "12",
        "row_padding": "0",
        "title": "Wholesale Order"
    })
    config.readfp(open(args.config))

    # Create a connection to CoreCommerce.
    cc_browser = cctools.CCBrowser(config.get("website", "base_url"),
                                   config.get("website", "username"),
                                   config.get("website", "password"))

    # Get product list.
    products = get_products(args, cc_browser)

    # Generate PDF file.
    logger.debug("Generating {}\n".format(os.path.abspath(args.pdf_file)))
    generate_pdf(args, config, cc_browser, products)

    logger.debug("Generation complete")
    return 0
Esempio n. 3
0
def fetch_inventory(args, config):
    """Fetch inventory data from CoreCommerce."""

    # Create a connection to CoreCommerce.
    cc_browser = cctools.CCBrowser(
        config.get("website", "base_url"),
        config.get("website", "username"),
        config.get("website", "password")
    )

    # Get list of products.
    products = cc_browser.get_products()

    # Sort products by category, product_name.
    products = sorted(products, key=cc_browser.product_key_by_cat_and_name)

    # Get list of variants.
    variants = cc_browser.get_variants()
    variants = sorted(variants, key=cc_browser.variant_key)

    # Group products by category.
    inventory = []
    for _, product_group in itertools.groupby(
        products,
        key=cc_browser.product_key_by_category
    ):
        # Assemble product data for the product_group.
        category_products = None
        for product in product_group:
            if product["Available"] == "N":
                continue

            category_name = product["Category"]
            if category_products is None:
                category_products = []
                inventory.append((category_name, category_products))

            product_sku = product["SKU"]
            product_name = product["Product Name"]
            product_level = product["Inventory Level"]
            if product["Track Inventory"] == "By Product":
                enabled = product["Available"]
                category_products.append(
                    (product_sku, product_name, product_level, enabled)
                )
            else:
                for variant in variants:
                    if product_sku == variant["Product SKU"]:
                        variant_sku = variant["Variant SKU"]
                        if variant_sku == "":
                            sku = product_sku
                        else:
                            sku = "{}-{}".format(product_sku, variant_sku)
                        answer = variant["Variant Name"]
                        if answer == "Assorted":
                            continue
                        name = "{} ({})".format(product_name, answer)
                        variant_inventory_level = variant[
                            "Variant Inventory Level"
                        ]
                        enabled = variant["Variant Enabled"]
                        category_products.append(
                            (
                                sku,
                                name,
                                variant_inventory_level,
                                enabled
                            )
                        )

    return inventory
Esempio n. 4
0
def main():
    """main"""
    default_config = os.path.join(
        os.path.dirname(os.path.abspath(__file__)),
        "cctools.cfg"
    )

    today = datetime.date.today()
    default_pdf_filename = "{:4}-{:02}-{:02}-ArtMartCheckInOut.pdf".format(
        today.year,
        today.month,
        today.day
    )

    arg_parser = argparse.ArgumentParser(
        description="Generates an Art Mart Inventory Sheet in PDF form."
    )
    arg_parser.add_argument(
        "--config",
        dest="config",
        metavar="FILE",
        default=default_config,
        help="configuration filename (default=%(default)s)"
    )
    arg_parser.add_argument(
        "--quantfile",
        dest="quant_filename",
        metavar="CSV_FILE",
        default="ArtMartQuantities.csv",
        help="input product quantities filename (default=%(default)s)"
    )
    arg_parser.add_argument(
        "--outfile",
        dest="pdf_filename",
        metavar="PDF_FILE",
        default=default_pdf_filename,
        help="output PDF filename (default=%(default)s)"
    )
    arg_parser.add_argument(
        "--write-quant",
        action="store_true",
        dest="write_quant",
        default=False,
        help="write template quantity file instead of PDF"
    )
    arg_parser.add_argument(
        "--verbose",
        action="store_true",
        default=False,
        help="display progress messages"
    )

    # Parse command line arguments.
    args = arg_parser.parse_args()

    # Configure logging.
    logging.basicConfig(
        level=logging.INFO if args.verbose else logging.WARNING
    )
    logger = logging.getLogger()

    # Also log using notify-send if it is available.
    if notify_send_handler.NotifySendHandler.is_available():
        logger.addHandler(
            notify_send_handler.NotifySendHandler(
                os.path.splitext(os.path.basename(__file__))[0]
            )
        )

    # Read config file.
    config = ConfigParser.RawConfigParser()
    config.readfp(open(args.config))

    # Create a connection to CoreCommerce.
    cc_browser = cctools.CCBrowser(
        config.get("website", "base_url"),
        config.get("website", "username"),
        config.get("website", "password")
    )

    # Fetch products list.
    products = cc_browser.get_products()

    # Sort products by category, product_name.
    products = sorted(
        products,
        key=cc_browser.product_key_by_cat_and_name
    )

    if args.write_quant:
        logger.debug("Generating {}".format(args.quant_filename))
        write_quantities(args.quant_filename, products)

    else:
        quantities = load_quantities(args.quant_filename)
        pdf_filename = args.pdf_filename
        logger.debug("Generating {}".format(pdf_filename))
        generate_pdf(products, quantities, pdf_filename)

    logger.debug("Generation complete")
    return 0
def main():
    """main"""
    default_config = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                  "cctools.cfg")
    now = datetime.datetime.now()
    default_xlsx_filename = now.strftime("%Y-%m-%d-WholesaleLineSheet.xlsx")

    arg_parser = argparse.ArgumentParser(
        description="Generates a wholesale line sheet.")
    arg_parser.add_argument(
        "--config",
        dest="config",
        metavar="FILE",
        default=default_config,
        help="configuration filename (default=%(default)s)")
    arg_parser.add_argument("--price-multiplier",
                            type=float,
                            metavar="M",
                            help="retail price multiplier (default=1.0)")
    arg_parser.add_argument("--price-precision",
                            type=float,
                            metavar="P",
                            default=0.01,
                            help="precision of prices (default=%(default).2f)")
    arg_parser.add_argument(
        "--wholesale-fraction",
        type=float,
        metavar="F",
        default=0.5,
        help="wholesale price fraction (default=%(default).2f)")
    arg_parser.add_argument(
        "--valid-ndays",
        metavar="N",
        type=int,
        default=30,
        help="number of days prices are valid (default=%(default)i)")
    arg_parser.add_argument("--outfile",
                            dest="xlsx_filename",
                            metavar="FILE",
                            default=default_xlsx_filename,
                            help="output XLSX filename (default=%(default)s)")
    arg_parser.add_argument("--include-variants",
                            action="store_true",
                            default=False,
                            help="add row for each product variant")
    arg_parser.add_argument("--exclude-sku",
                            action="append",
                            dest="exclude_skus",
                            metavar="SKU",
                            help="exclude SKU from output")
    arg_parser.add_argument("--verbose",
                            action="store_true",
                            default=False,
                            help="display progress messages")

    # Parse command line arguments.
    args = arg_parser.parse_args()

    # Configure logging.
    logging.basicConfig(
        level=logging.INFO if args.verbose else logging.WARNING)
    logger = logging.getLogger()

    # Also log using notify-send if it is available.
    if notify_send_handler.NotifySendHandler.is_available():
        logger.addHandler(
            notify_send_handler.NotifySendHandler(
                os.path.splitext(os.path.basename(__file__))[0]))

    # Read config file.
    config = ConfigParser.RawConfigParser()
    config.readfp(open(args.config))

    # Handle the price multiplier.
    if args.price_multiplier is None:
        price_multiplier = get_optional_option(config, "wholesale_line_sheet",
                                               "price_multiplier")
        if price_multiplier is None:
            args.price_multiplier = 1.0
        else:
            args.price_multiplier = float(price_multiplier)

    # Create a connection to CoreCommerce.
    cc_browser = cctools.CCBrowser(config.get("website", "base_url"),
                                   config.get("website", "username"),
                                   config.get("website", "password"))

    # Fetch products list.
    products = cc_browser.get_products()

    # Generate spreadsheet.
    logger.debug("Generating {}".format(args.xlsx_filename))
    generate_xlsx(args, config, cc_browser, products)

    logger.debug("Generation complete")
    return 0
Esempio n. 6
0
    def run_checks_core(self):
        """Run all checks, returning a list of findings."""

        self.clear_finding_list()

        findings = []

        # Create a connection to CoreCommerce.
        cc_browser = cctools.CCBrowser(
            self.config.get("website", "base_url"),
            self.config.get("website", "username"),
            self.config.get("website", "password"),
            clean=self.args.clean,
            cache_ttl=0 if self.args.refresh_cache else self.args.cache_ttl
        )

        # Any subsequent calls should ignore the cache.  If the user
        # clicks the Refresh button, it would be because they changed
        # something in CoreCommerce.
        self.args.refresh_cache = True

        # Check category list.
        categories = cc_browser.get_categories()
        self.eval_locals["items"] = categories
        for category in categories:
            findings.extend(
                self.check_item(
                    "category",
                    category,
                    category["Category Name"]
                )
            )

        # Check products list.
        cc_browser.guess_product_ids()
        products = sorted(
            cc_browser.get_products(),
            key=cc_browser.product_key_by_cat_and_name
        )
        self.eval_locals["items"] = products
        findings.extend(check_skus(self.config, products))
        for product in products:
            for key in ["Teaser"]:
                product[key] = cctools.html_to_plain_text(product[key])
            findings.extend(
                self.check_item(
                    "product",
                    product,
                    product_display_name(product)
                )
            )

        # Check variants list.
        variants = sorted(
            cc_browser.get_variants(),
            key=cc_browser.variant_key_by_cat_product
        )
        add_is_first_answer_flag(variants)
        self.eval_locals["items"] = variants
        for variant in variants:
            findings.extend(
                self.check_item(
                    "variant",
                    variant,
                    variant_display_name(variant)
                )
            )

        self.checks_completed()

        return findings
Esempio n. 7
0
def main():
    """main"""
    # Construct default filename of configuration file.
    default_config = os.path.join(
        os.path.dirname(os.path.abspath(__file__)),
        "cctools.cfg"
    )

    arg_parser = argparse.ArgumentParser(
        description="Generates a price list from CoreCommerce data."
    )
    arg_parser.add_argument(
        "--config",
        metavar="FILE",
        default=default_config,
        help="configuration filename (default=%(default)s)"
    )
    arg_parser.add_argument(
        "--category",
        action="append",
        dest="categories",
        metavar="CAT",
        help="include category in output"
    )
    arg_parser.add_argument(
        "--exclude-category",
        action="append",
        dest="exclude_categories",
        metavar="CAT",
        help="exclude category from output"
    )
    arg_parser.add_argument(
        "--exclude-sku",
        action="append",
        dest="exclude_skus",
        metavar="SKU",
        help="exclude SKU from output"
    )
    arg_parser.add_argument(
        "--pdf-file",
        metavar="PDF_FILE",
        default="PriceListRetailTaxInc.pdf",
        help="output PDF filename (default=%(default)s)"
    )
    arg_parser.add_argument(
        "--add-sku",
        action="store_true",
        default=False,
        help="append SKU to product name"
    )
    arg_parser.add_argument(
        "--add-teaser",
        action="store_true",
        default=False,
        help="add teaser line"
    )
    arg_parser.add_argument(
        "--ncols",
        type=int,
        metavar="N",
        default=None,
        help="number of report columns (default=2)"
    )
    arg_parser.add_argument(
        "--greybar-interval",
        type=int,
        metavar="N",
        default=2,
        help="greybar interval (default=%(default)i)"
    )
    arg_parser.add_argument(
        "--discount",
        type=float,
        dest="discount_percent",
        metavar="PCT",
        default=30,
        help="discount in percent (default=%(default).0f)"
    )
    arg_parser.add_argument(
        "--avg-tax",
        type=float,
        dest="avg_tax_percent",
        metavar="PCT",
        default=8.3,
        help="average sales tax rate in percent (default=%(default).2f)"
    )
    arg_parser.add_argument(
        "--verbose",
        action="store_true",
        default=False,
        help="display progress messages"
    )

    # Parse command line arguments.
    args = arg_parser.parse_args()
    if args.categories and args.exclude_categories:
        arg_parser.error("--category and --exclude-category specified")
    if args.ncols is None:
        if args.add_teaser:
            args.ncols = 1
        else:
            args.ncols = 2

    # Configure logging.
    logging.basicConfig(
        level=logging.INFO if args.verbose else logging.WARNING
    )
    logger = logging.getLogger()

    # Also log using notify-send if it is available.
    if notify_send_handler.NotifySendHandler.is_available():
        logger.addHandler(
            notify_send_handler.NotifySendHandler(
                os.path.splitext(os.path.basename(__file__))[0]
            )
        )

    # Read config file.
    config = ConfigParser.SafeConfigParser({
        "body_fontsize": "12",
        "row_padding": "0"
    })
    config.readfp(open(args.config))

    # Create a connection to CoreCommerce.
    cc_browser = cctools.CCBrowser(
        config.get("website", "base_url"),
        config.get("website", "username"),
        config.get("website", "password")
    )

    # Get product list.
    products = get_products(args, cc_browser)

    # Generate PDF file.
    logger.debug("Generating {}\n".format(os.path.abspath(args.pdf_file)))
    generate_pdf(
        args,
        config,
        cc_browser,
        products
    )

    logger.debug("Generation complete")
    return 0
Esempio n. 8
0
def fetch_inventory(args, config):
    """Fetch inventory data from CoreCommerce."""

    # Create a connection to CoreCommerce.
    cc_browser = cctools.CCBrowser(
        config.get("website", "base_url"),
        config.get("website", "username"),
        config.get("website", "password")
    )

    # Get list of products.
    products = cc_browser.get_products()

    # Sort products.
    if args.sort == "SKU":
        key = cc_browser.product_key_by_sku
    else:
        key = cc_browser.product_key_by_cat_and_name
    products = sorted(products, key=key)

    # Get list of variants.
    variants = cc_browser.get_variants()
    variants = sorted(variants, key=cc_browser.variant_key)

    inventory = list()
    for product in products:
        if product["Available"] == "N":
            continue
        product_sku = product["SKU"]
        product_name = product["Product Name"]
        product_level = product["Inventory Level"]
        if product["Track Inventory"] == "By Product":
            enabled = product["Available"]
            main_photo = product["Main Photo (Image)"]
            inventory.append(
                (product_sku, product_level, product_name, enabled, main_photo)
            )
        else:
            for variant in variants:
                if product_sku == variant["Product SKU"]:
                    variant_sku = variant["Variant SKU"]
                    if variant_sku == "":
                        sku = product_sku
                    else:
                        sku = "{}-{}".format(product_sku, variant_sku)
                    variant_inventory_level = variant[
                        "Variant Inventory Level"
                    ]
                    answer = variant["Variant Name"]
                    name = "{} ({})".format(product_name, answer)
                    enabled = variant["Variant Enabled"]
                    main_photo = variant["Variant Main Photo (Image)"]
                    inventory.append(
                        (
                            sku,
                            variant_inventory_level,
                            name,
                            enabled,
                            main_photo
                        )
                    )

    # for sku, level, name in inventory:
    #     print("{:9} {:4} {}".format(sku, level, name))
    return inventory