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") #####################################################################
def test_order_status(self): orderServices = OrderManager()
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'
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