コード例 #1
0
from lecopain.helpers.pagination import Pagination

from sqlalchemy import extract
from datetime import datetime

from flask import Blueprint, render_template, redirect, url_for, Flask, request, jsonify
from flask_login import login_required

from lecopain.helpers.roles_utils import admin_login_required

app = Flask(__name__, instance_relative_config=True)

order_page = Blueprint('order_page', __name__,
                       template_folder='../templates')

orderServices = OrderManager()
customerService = CustomerManager()
productService = ProductManager()



#####################################################################
#                                                                   #
#####################################################################
@order_page.route("/orders", methods=['GET', 'POST'])
@login_required
@admin_login_required
def orders():
    return render_template('/orders/orders.html', title="Commandes")

#####################################################################
コード例 #2
0
 def test_order_status(self):
     orderServices = OrderManager()
コード例 #3
0
class ReportManager():

    orderServices = OrderManager()
    shipmentServices = ShipmentManager()

    def prepareAmount(self, orders, dt=None):
        amount = {'price': 0.0, 'nb_products': 0, 'nb_orders': 0}
        products = []
        amount_shipping_price = 0.0
        amount_price = 0.0
        for order in orders:
            shipping_day = order['shipping_dt'].day
            if dt is None or int(shipping_day) == dt.day:

                amount_price = (amount_price + order['price'])
                amount['nb_products'] = int(amount['nb_products']) + \
                order['nb_products']

        amount['price'] = format(amount_price, '.2f')
        amount['products'] = self.orderServices.extract_products_from_orders(
            orders, dt)
        amount['nb_orders'] = len(orders)
        return amount

    def prepareLines_by_customer(self, orders, dt):
        lines = []

        for order in orders:
            shipping_day = order['shipping_dt'].day
            if int(shipping_day) == dt.day:
                line = {
                    'customer': order['customer_name'],
                    'address': order['customer_address']
                }
                line['products'] = []
                for order_line in order['lines']:
                    line['products'].append({
                        'name':
                        order_line['product_short_name'],
                        'quantity':
                        order_line['quantity']
                    })
                lines.append(line)
        return lines

    def prepareDay(self, day, orders, dt):
        day['amount'] = self.prepareAmount(orders, dt)
        day['lines'] = self.prepareLines_by_customer(orders, dt)
        return day

    def get_reports_by_seller(self, seller_id, customer_id, period, day):
        days = []
        datetime_day = datetime.strptime(day, '%d%m%Y')
        start, end = dates_range(period, datetime_day)

        if period == Period_Enum.DAY.value:
            start = start + timedelta(seconds=1)

        while start <= end:
            end_day = start + timedelta(days=1)

            day = {}
            orders = self.orderServices.get_all_by_seller_customer_period_valid(
                seller_id, customer_id, start, end_day)

            start = start + timedelta(seconds=1)
            day['date'] = start

            day = self.prepareDay(day, orders, start)
            days.append(day)
            start = end_day
        return days

    def get_main_amounts_by_seller(self, seller_id, customer_id, period, day):
        days = []
        datetime_day = datetime.strptime(day, '%d%m%Y')
        start, end = dates_range(period, datetime_day)

        orders = self.orderServices.get_all_by_seller_customer_period_valid(
            seller_id, customer_id, start, end)

        return self.prepareAmount(orders)

    def get_reports_by_customer(self, customer_id, period, day):

        report = {}
        nb_products = 0
        shipping_price = 0.0
        shipments = self.shipmentServices.get_some_valid(
            customer_id, day, period)

        for shipment in shipments:
            nb_products = nb_products + shipment['nb_products']
            shipping_price = shipping_price + shipment['shipping_price']

        report['nb_shipments'] = len(shipments)
        report['nb_products'] = nb_products
        report['shipping_price'] = format(shipping_price, '.2f')
        report['shipments'] = shipments

        return report

    def test_excel_report(self, seller_id, customer_id, period, day):

        days = self.get_reports_by_seller(seller_id, customer_id, period, day)
        workbook = xlsxwriter.Workbook('/tmp/report.xlsx')
        worksheet = workbook.add_worksheet()

        LIGHT_BLUE = '#dbfcfd'
        LIGHT_YELLOW = '#fcfddb'

        row = 0
        col = 0
        column_width = 0
        cell_format_date = workbook.add_format(
            {'num_format': 'ddd dd mmm yyyy'})
        cell_format_date.set_pattern(
            1)  # This is optional when using a solid fill.
        cell_format_date.set_bg_color('white')
        cell_format_date.set_bold(True)
        cell_format_date.set_border()
        cell_format_date.set_align('center')

        cell_format_amounts = workbook.add_format()
        cell_format_amounts.set_pattern(
            1)  # This is optional when using a solid fill.
        cell_format_amounts.set_bg_color('#e6e8e8')
        cell_format_amounts.set_border()
        cell_format_amounts.set_align('center')

        cell_format_name = workbook.add_format()
        cell_format_name.set_pattern(
            1)  # This is optional when using a solid fill.
        cell_format_name.set_bg_color(LIGHT_BLUE)
        cell_format_name.set_left()
        cell_format_name.set_right(right=0)
        cell_format_name.set_text_wrap()

        cell_format_address = workbook.add_format()
        cell_format_address.set_pattern(
            1)  # This is optional when using a solid fill.
        cell_format_address.set_bg_color(LIGHT_BLUE)
        cell_format_address.set_left()
        cell_format_address.set_right()
        cell_format_address.set_bottom()

        cell_format_products = workbook.add_format()
        cell_format_products.set_pattern(
            1)  # This is optional when using a solid fill.
        cell_format_products.set_bg_color('#ffffff')
        cell_format_products.set_left()
        cell_format_products.set_right()

        customer_addresses = []

        for day in days:
            row = 0
            worksheet.merge_range(row, col, row, col + 1, '')
            worksheet.write_datetime(row, col, day['date'], cell_format_date)
            row = row + 1
            amounts_line = 'Prix : ' + str(
                day['amount']['price']) + ' € - Nb. commandes : ' + str(
                    day['amount']['nb_orders']) + ' - Totaux :'
            for product_amounts in day['amount']['products']:
                amounts_line = amounts_line + (
                    str(product_amounts['short_name']) + ' x' +
                    str(product_amounts['quantity']) + ', ')
            worksheet.merge_range(row, col, row, col + 1, '')
            worksheet.write(row, col, amounts_line, cell_format_amounts)
            row = row + 1
            for line in day['lines']:
                not_found = False
                for customer_address in customer_addresses:
                    if customer_address['name'] == line['customer']:
                        not_found = True
                if not_found is False:
                    customer_addresses.append({
                        "name": line['customer'],
                        "address": line['address']
                    })

                worksheet.set_row(row, 40)
                worksheet.set_column(col, col, 20)
                worksheet.write(row, col, line['customer'], cell_format_name)
                products_line = ''
                for line_product in line['products']:
                    products_line = products_line + (
                        str(line_product['name']) + ' x' +
                        str(line_product['quantity']) + ', ')
                if (len(products_line) > column_width):
                    width = len(products_line)
                    worksheet.set_column(col + 1, col + 1, 30)
                worksheet.write(row, col + 1, products_line,
                                cell_format_products)
                row = row + 1
                if cell_format_address.bg_color == LIGHT_BLUE:
                    cell_format_address.set_bg_color(LIGHT_YELLOW)
                    cell_format_name.set_bg_color(LIGHT_YELLOW)
                else:
                    cell_format_address.set_bg_color(LIGHT_BLUE)
                    cell_format_name.set_bg_color(LIGHT_BLUE)
            col = col + 3
            column_width = 0

        row = 0
        worksheet.write(row, col, 'Adresses', cell_format_date)
        row = 1
        for customer_address in customer_addresses:
            worksheet.merge_range(row, col, row, col + 6, '')
            worksheet.write(
                row, col,
                customer_address['name'] + " : " + customer_address['address'],
                cell_format_address)
            row = row + 1

        workbook.close()
        return '/tmp/report.xlsx'
コード例 #4
0
class ShipmentManager():

    businessService = BusinessService()
    itemService = ItemService()
    orderService = OrderManager()

    def parse_lines(self, lines):
        headers = ('product_id', 'seller_id', 'quantity', 'price')
        items = [{} for i in range(len(lines[0]))]
        for x, i in enumerate(lines):
            for _x, _i in enumerate(i):
                items[_x][headers[x]] = _i
        return items

    def sort_lines_by_seller(self, lines):
        sorted_lines = []
        for line in lines:
            res_line = [
                sorted_line for sorted_line in sorted_lines
                if sorted_line["seller_id"] == line['seller_id']
            ]
            new_line = {
                'product_id': line['product_id'],
                'quantity': line['quantity'],
                'price': line['price']
            }

            if len(res_line) > 0:
                res_line[0]['lines'].append(new_line)
            else:
                sorted_lines.append({
                    'seller_id': line['seller_id'],
                    'lines': [new_line]
                })

        return sorted_lines

    def create_shipment_and_parse_line(self, shipment, lines):
        parsed_lines = self.parse_lines(lines)
        self.create_shipment(shipment, parsed_lines)

    def create_shipment(self, shipment, lines):
        created_shipment = ShipmentDao.create_shipment(shipment)
        sorted_lines = self.sort_lines_by_seller(lines)
        for grouped_lines in sorted_lines:
            self.orderService.create_by_shipment(created_shipment,
                                                 grouped_lines['lines'],
                                                 grouped_lines['seller_id'])
            db.session.commit()
            if created_shipment.category != Category_Enum.PRESTATION.value:
                created_shipment.shipping_price, created_shipment.shipping_rules = self.businessService.apply_rules_for_shipment(
                    created_shipment)
            else:
                created_shipment.shipping_price, created_shipment.shipping_rules = self.businessService.prestation_rules_for_shipment(
                    created_shipment)
            db.session.commit()
        if created_shipment.subscription_id is not None:
            self.items_add_subscription(created_shipment)

    def delete_shipment(self, shipment_id):
        shipment = ShipmentDao.get_one(shipment_id)
        if shipment.subscription_id is not None and shipment.status != ShipmentStatus_Enum.ANNULEE.value:
            self.remove_shipment_subscriptions(shipment)
        ShipmentDao.delete(shipment_id)
        ShipmentDao.update_db(shipment)

    def update_shipment_and_parse_line(self, category, shipment_id, lines):
        shipment = ShipmentDao.get_one(shipment_id)
        shipment.category = category

        #remove shipment from subscription
        if shipment.subscription != None:
            self.remove_shipment_subscriptions(shipment)

        # init to 0 shipment
        shipment.init_stats()

        parsed_lines = self.parse_lines(lines)
        sorted_lines = self.sort_lines_by_seller(parsed_lines)

        for order in shipment.orders:
            b_delete = True
            for grouped_lines in sorted_lines:
                if str(order.seller_id) == grouped_lines['seller_id']:
                    b_delete = False
            if (b_delete):
                shipment.remove_order(order)

        for grouped_lines in sorted_lines:
            self.orderService.update_by_shipment(shipment,
                                                 grouped_lines['lines'],
                                                 grouped_lines['seller_id'])

        if shipment.category != Category_Enum.PRESTATION.value:
            shipment.shipping_price, shipment.shipping_rules = self.businessService.apply_rules_for_shipment(
                shipment)
        else:
            shipment.shipping_price, shipment.shipping_rules = self.businessService.prestation_rules_for_shipment(
                shipment)

        shipment.updated_at = datetime.now()

        if shipment.subscription != None:
            self.add_shipment_subscriptions(shipment)

        db.session.commit()

    def remove_shipment_subscriptions(self, shipment):
        subscription = SubscriptionDao.get_one(shipment.subscription_id)
        itemService = ItemService()
        itemService.decrement_subscription_nb_shipments(subscription) \
            .remove_shipment_subscription_nb_products(subscription, shipment.nb_products) \
            .remove_shipment_subscription_shipping_price(subscription, shipment.shipping_price) \
            .remove_shipment_subscription_nb_orders(subscription, shipment.nb_orders)
        SubscriptionDao.update_db(subscription, itemService.items)

    def add_shipment_subscriptions(self, shipment):
        subscription = SubscriptionDao.get_one(shipment.subscription_id)
        itemService = ItemService()
        itemService.increment_subscription_nb_shipments(subscription) \
            .add_shipment_subscription_nb_products(subscription, shipment.nb_products) \
            .add_shipment_subscription_shipping_price(subscription, shipment.shipping_price) \
            .add_shipment_subscription_nb_orders(subscription, shipment.nb_orders)
        SubscriptionDao.update_db(subscription, itemService.items)

    def items_remove_subscription(self, shipment):
        subscription = SubscriptionDao.get_one(shipment.subscription_id)
        itemService = ItemService()
        itemService.remove_shipment_subscription_nb_products(subscription, shipment.nb_products) \
            .remove_shipment_subscription_shipping_price(subscription, shipment.shipping_price) \
            .decrement_subscription_nb_shipments(subscription) \
            .remove_shipment_subscription_nb_orders(subscription, shipment.nb_orders)
        SubscriptionDao.update_db(subscription, itemService.items)

    def items_add_subscription(self, shipment):
        subscription = SubscriptionDao.get_one(shipment.subscription_id)
        itemService = ItemService()
        itemService.add_shipment_subscription_nb_products(subscription, shipment.nb_products) \
            .add_shipment_subscription_shipping_price(subscription, shipment.shipping_price) \
            .increment_subscription_nb_shipments(subscription) \
            .add_shipment_subscription_nb_orders(subscription, shipment.nb_orders)
        SubscriptionDao.update_db(subscription, itemService.items)

    # @
    #
    def update_shipment_status(self, shipment_id, shipment_status):
        shipment = ShipmentDao.get_one(shipment_id)
        if shipment.status != shipment_status:
            if shipment_status == ShipmentStatus_Enum.ANNULEE.value and shipment.subscription_id is not None:
                self.items_remove_subscription(shipment)

            if shipment_status == ShipmentStatus_Enum.CREE.value and shipment.subscription_id is not None:
                self.items_add_subscription(shipment)

            for order in shipment.orders:
                order.status = shipment_status
            ShipmentDao.update_status(shipment_id, shipment_status)

    # @
    #
    def update_shipment_shipping_status(self, shipment_id, shipping_status):
        ShipmentDao.update_shipping_status(shipment_id, shipping_status)

    # @
    #
    def update_shipment_payment_status(self, shipment_id, payment_status):
        ShipmentDao.update_payment_status(shipment_id, payment_status)

    # @
    #
    def get_in_progess_shipments_counter(self):
        return Shipment.query.filter(
            Shipment.status == ShipmentStatus_Enum.CREE.value).count()

    # @
    #
    def get_latest_shipments_counter(self):
        date_since_2_days = date.today() - timedelta(days=2)
        return Shipment.query.filter(
            Shipment.created_at > date_since_2_days).count()

    def get_all(self):
        return ShipmentDao.read_all()

    def get_all_by_subscription(self, subscription_id, nocanceled, nopaid):
        return ShipmentDao.read_by_subscription(subscription_id, nocanceled,
                                                nopaid)

    def get_all_by_subscription_pagination(self,
                                           subscription_id,
                                           page=1,
                                           per_page=10):
        return ShipmentDao.read_by_subscription_pagination(
            subscription_id, page, per_page)

    def get_by_customer_by_period(self,
                                  customer_id=0,
                                  day=datetime.utcnow,
                                  period=Period_Enum.ALL.value,
                                  nocanceled=False,
                                  nopaid=False):
        datetime_day = datetime.strptime(day, '%d%m%Y')
        start, end = dates_range(period, datetime_day)
        return ShipmentDao.read_by_customer_by_period(customer_id,
                                                      start=start,
                                                      end=end,
                                                      nocanceled=nocanceled,
                                                      nopaid=nopaid)

    def count_by_customer(self, customer_id):
        return ShipmentDao.count_by_customer(customer_id)

    def sum_by_customer(self, customer_id):
        return ShipmentDao.sum_by_customer(customer_id)

    def count_canceled_by_customer(self, customer_id):
        return ShipmentDao.count_canceled_by_customer(customer_id)

    def get_all_by_customer_pagination(self, customer_id, page=1, per_page=10):
        return ShipmentDao.read_by_customer_pagination(customer_id, page,
                                                       per_page)

    def get_some(self,
                 customer_id=0,
                 day=datetime.utcnow,
                 period=Period_Enum.ALL.value):
        datetime_day = datetime.strptime(day, '%d%m%Y')
        start, end = dates_range(period, datetime_day)
        return ShipmentDao.read_some(customer_id=customer_id,
                                     start=start,
                                     end=end)

    def get_some_pagination(self,
                            customer_id=0,
                            day=datetime.utcnow,
                            period=Period_Enum.ALL.value,
                            page=1,
                            per_page=30,
                            nocanceled=False,
                            nopaid=False):
        datetime_day = datetime.strptime(day, '%d%m%Y')
        start, end = dates_range(period, datetime_day)
        return ShipmentDao.read_some_pagination(customer_id=customer_id,
                                                start=start,
                                                end=end,
                                                page=page,
                                                per_page=per_page,
                                                nocanceled=nocanceled,
                                                nopaid=nopaid)

    def get_some_valid(self,
                       customer_id=0,
                       day=datetime.utcnow,
                       period=Period_Enum.ALL.value):
        datetime_day = datetime.strptime(day, '%d%m%Y')
        start, end = dates_range(period, datetime_day)
        return ShipmentDao.read_some_valid(customer_id=customer_id,
                                           start=start,
                                           end=end)

    def get_one(self, shipment_id):
        return ShipmentDao.read_one(shipment_id)

    def get_shipment_status(self):
        return list(map(lambda c: c.value, ShipmentStatus_Enum))

    def update_shipping_dt(self, shipment, shipping_dt):
        ShipmentDao.update_shipping_dt(shipment['id'], shipping_dt)

    def find(self, products, short_name):
        for product in products:
            if product['short_name'] == short_name:
                return product
        return None

    def extract_products_from_shipments(self, shipments):
        products = []
        product = None
        for shipment in shipments:
            for line in shipment['lines']:
                short_name = line['product_short_name']
                quantity = line['quantity']
                product = self.find(products, short_name)
                if product != None:
                    #line_tmp = [d for d in shipment['lines'] if d['line']['product_short_name'] == short_name]
                    product['quantity'] = product['quantity'] + int(
                        line['quantity'])
                else:
                    products.append({
                        'short_name': line['product_short_name'],
                        'quantity': int(line['quantity'])
                    })
        return products

    def get_total_price(self, shipment):
        price = 0.0
        for order in shipment.orders:
            price = price + order.price