Created
May 11, 2016 06:36
-
-
Save ricardosiri68/006997ea326dc3ad48e1b3d45a34af5b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
id | name | |
---|---|---|
0 | Pedro | |
1 | Juan | |
2 | Diego | |
3 | Luisa | |
4 | Marta |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import services | |
import sys | |
import os | |
clients_service = services.ClientsService() | |
products_service = services.ProductsService() | |
bills_service = services.BillsService() | |
sellings_service = services.SellingsService() | |
def clear_screen(): | |
'''limpiar lo que hay en la pantalla''' | |
os.system('cls' if os.name == 'nt' else 'clear') | |
def get_object_loop(func): | |
'''este decorador mantiene espera la entrada del usuario''' | |
def wrapper(): | |
while True: | |
try: | |
return func(int(input('> '))) | |
except IndexError: | |
print('La id ingresada no se encuentra en el servicio') | |
except ValueError: | |
print('La id debe ser un numero entero') | |
return wrapper | |
def show_clients(): | |
'''muestra la lista de clientes''' | |
for client in clients_service: | |
print('{client.id:04d} | {client.name}'.format(client=client)) | |
def show_clients_totals(): | |
'''muestra la suma total de lo vendido a cada cliente''' | |
for client, cant, total in sellings_service.clients_totals(): | |
print('{client.id:04d} | {client.name:^30} | {cant:4d} |' | |
' $ {total:8.2f}'.format(client=client, cant=cant, total=total)) | |
def show_products_counts(): | |
'''muestra la cantidad vendida de cada producto''' | |
for product, count in sellings_service.products_counts(): | |
print('{product.id:04d} | {product.name:^30} | {count}' | |
.format(product=product, count=count)) | |
def show_products(): | |
'''muestra la lista de productos''' | |
for product in products_service: | |
print('{product.id:04d} | {product.name:<30} | $ {product.price:8.2f}' | |
.format(product=product)) | |
def show_bills(): | |
'''muestra todas las boletas de venta''' | |
for bill in bills_service: | |
print('{bill.id:04d} | $ {bill.total:8.2f}'.format(bill=bill)) | |
def show_bell_sellings(bill): | |
'''muestra todos los articulos de una venta''' | |
print('boleta ID: %s ' % bill.id) | |
show_sellings(bill.sellings) | |
print('total $ %8.2f' % bill.total) | |
def show_sellings(sellings=sellings_service): | |
for sell in sellings: | |
print('{sell.bill_id:04d} | {sell.client.name:<15} | {sell.cant:4.1f} |' | |
' {sell.product.name:^25} | $ {sell.product.price:8.2f} |' | |
' $ {sell.amount:8.2f}'.format(sell=sell)) | |
def show_bill(): | |
'''muestra muestra el detalle de una boleta segun si id''' | |
print('ingrese el numero de boleta') | |
bill = get_bill() | |
show_bell_sellings(bill) | |
@get_object_loop | |
def get_bill(bill_id): | |
'''obtiene un boleta segun su id''' | |
return bills_service[bill_id] | |
@get_object_loop | |
def get_client(client_id): | |
'''obtiene un cliente según su id''' | |
return clients_service[int(client_id)] | |
@get_object_loop | |
def get_product(product_id): | |
'''obtiene un producto según su id''' | |
return products_service[int(product_id)] | |
def get_cant(): | |
'''recupera la cantidad de un productos de un reglon de venta''' | |
while True: | |
try: | |
return float(input('> ')) | |
except ValueError: | |
print('la cantidad ingresada debe ser un numero') | |
def make_newsale(): | |
'''lleva cabo una nueva venta''' | |
# a) Determinar el nuevo numero de boleta, basado en lista de ventas. | |
# b) muestra el listado de usuarios, el vendedor ingresa el numero de | |
# cliente | |
# c) muestra el listado de productos, el vendedor ingresa el numero de | |
# producto | |
# d) pide la cantidad de items para ese producto. | |
# e) pregunta si hay q ingresar mas productos | |
# f) si no hay q ingresar mas productos, se presenta un resumen de la | |
# boleta, indicando los productos vendidos, su cantidad, precio unitario y | |
# precio por item. | |
# g) Finalmente, se presenta el total a pagar. | |
# h) Estos datos deben quedar almacendos en la lista ventas, de manera de | |
# poder ver reportes de ventas posteriores | |
new_bill = bills_service.create() | |
show_clients() | |
client = get_client() | |
if not client: | |
return | |
while True: | |
show_products() | |
product = get_product() | |
if not product: | |
return | |
print('ingrese la cantidad a despachar') | |
cant = get_cant() | |
sellings_service.create(new_bill, client, cant, product) | |
if input('añadir nuevo') == 's': | |
clear_screen() | |
else: | |
break | |
show_bell_sellings(new_bill) | |
def show_mainmenu(): | |
'''muestra el menu principal de la aplicacion''' | |
clear_screen() | |
print('ingrese opcion:\n' | |
'1 realizar nueva venta\n' | |
'2 listar productos y precios\n' | |
'3 listar clientes\n' | |
'4 listar ventas\n' | |
'5 ver boleta N°\n' | |
'6 listar suma de ventas por cliente\n' | |
'7 listar cantidad vendida por producto\n' | |
'8 listar boletas\n' | |
'm mostras este menu\n' | |
's salir') | |
def main(): | |
'''metodo principal donde se encuentra el map de las acciones del usario y | |
el mainloop de ejecucion''' | |
main_actions = { | |
'1': make_newsale, | |
'2': show_products, | |
'3': show_clients, | |
'4': show_sellings, | |
'5': show_bill, | |
'6': show_clients_totals, | |
'7': show_products_counts, | |
'8': show_bills, | |
'm': show_mainmenu, | |
's': sys.exit | |
} | |
show_mainmenu() | |
while True: | |
option = input('> ') | |
if option not in main_actions: | |
print('La opcion ingresada no es valida, intente nuevamente') | |
else: | |
main_actions[option]() # llamamos a la accion principal | |
if __name__ == "__main__": | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
id | name | price | |
---|---|---|---|
0 | Coca cola | 700 | |
1 | Ramitas bolsa | 300 | |
2 | Helado litro | 1200 | |
3 | Hielo bolsa | 500 | |
4 | Pisco 750cc | 1300 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bill_id | client_id | cant | product_id | |
---|---|---|---|---|
1 | 4 | 4 | 1 | |
1 | 4 | 4 | 3 | |
1 | 4 | 2 | 4 | |
2 | 3 | 5 | 3 | |
2 | 3 | 5 | 0 | |
3 | 2 | 1 | 2 | |
3 | 2 | 2 | 1 | |
3 | 2 | 2 | 3 | |
3 | 2 | 3 | 0 | |
4 | 0 | 4 | 1 | |
5 | 4 | 1 | 2 | |
5 | 4 | 5 | 1 | |
6 | 2 | 2 | 4 | |
6 | 2 | 5 | 3 | |
7 | 4 | 4 | 2 | |
7 | 4 | 3 | 1 | |
7 | 4 | 2 | 0 | |
7 | 4 | 1 | 3 | |
8 | 2 | 5 | 4 | |
8 | 2 | 1 | 3 | |
9 | 0 | 3 | 2 | |
10 | 2 | 5 | 1 | |
10 | 2 | 3 | 3 | |
10 | 2 | 4 | 4 | |
11 | 0 | 4 | 3 | |
11 | 0 | 5 | 0 | |
12 | 1 | 1 | 0 | |
12 | 1 | 3 | 1 | |
12 | 1 | 4 | 2 | |
13 | 4 | 4 | 1 | |
14 | 3 | 3 | 2 | |
14 | 3 | 5 | 0 | |
14 | 3 | 3 | 4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from collections import namedtuple | |
import csv | |
Client = namedtuple('Cliente', 'id name') | |
Product = namedtuple('Product', 'id name price') | |
SellTuple = namedtuple('Sell', 'bill_id client cant product') | |
BillTuple = namedtuple('Bill', 'id sellings') | |
ClientTotal = namedtuple('ClientSellingsTotal', 'client cant total') | |
ProductCount = namedtuple('ProductCount', 'product count') | |
class Bill(BillTuple): | |
@property | |
def total(self): | |
'''el total vendido de una boleta''' | |
return sum(sell.amount for sell in self.sellings) | |
class Sell(SellTuple): | |
@property | |
def amount(self): | |
'''el importe de de una venta''' | |
return self.cant * self.product.price | |
def get_csv_data(filename): | |
with open(filename) as csv_file: | |
reader = csv.DictReader(csv_file) | |
for item in reader: | |
yield tuple(item[fieldname] if fieldname != 'id' and | |
not fieldname.endswith('_id') else int(item[fieldname]) | |
for fieldname in reader.fieldnames) | |
class Service: | |
def __len__(self): | |
return len(self.items) | |
def __iter__(self): | |
for item in self.items: | |
yield item | |
def __getitem__(self, index): | |
'''obtiene un item segun su id''' | |
for item in self.items: | |
if item.id == index: | |
return item | |
raise IndexError('no hay un item con esa id en %s' % self.__class__) | |
class ClientsService(Service): | |
'''servicio de clientes''' | |
def __init__(self): | |
self.items = [Client(*item) for item in get_csv_data('clients.csv')] | |
class ProductsService(Service): | |
'''servicio de productos''' | |
def __init__(self): | |
self.items = [Product(p_id, name, float(price)) | |
for p_id, name, price in get_csv_data('products.csv')] | |
class BillsService(Service): | |
'''servicio de boletas''' | |
def __init__(self): | |
sellings = SellingsService() | |
bills_items = {} | |
for sell in sellings: | |
bills_items[sell.bill_id] = bills_items.get(sell.bill_id, []) + \ | |
[sell] | |
self.items = [Bill(bill_id, itemsellings) | |
for bill_id, itemsellings in bills_items.items()] | |
def create(self): | |
'''crea una boleta nueva y la añade a la lista''' | |
new_bill = Bill(max(item.id for item in self.items) + 1, []) | |
self.items.append(new_bill) | |
return new_bill | |
class SellingsService: | |
'''servicio de ventas''' | |
def __init__(self): | |
clients = ClientsService() | |
products = ProductsService() | |
sellings_csv = get_csv_data('sellings.csv') | |
self.items = [Sell(bill_id, clients[client_id], float(cant), | |
products[product_id]) | |
for bill_id, client_id, cant, product_id in sellings_csv] | |
def __len__(self): | |
return len(self.items) | |
def __iter__(self): | |
for sell in self.items: | |
yield sell | |
def create(self, bill, client, cant, product): | |
'''crea una nueva tupla de venta y la añade a la lista del servicio''' | |
sell = Sell(bill.id, client, cant, product) | |
self.items.append(sell) | |
bill.sellings.append(sell) | |
return sell | |
def clients_totals(self): | |
'''genera las tuplas de ClienteTotal de cada cliente''' | |
clients_totals = {} | |
for sell in self: | |
if sell.client in clients_totals: | |
client_total = clients_totals[sell.client] | |
clients_totals[sell.client] = ClientTotal(client_total.client, | |
client_total.cant + 1, client_total.total + sell.amount) | |
else: | |
clients_totals[sell.client] = ClientTotal(sell.client, 1, | |
sell.amount) | |
return clients_totals.values() | |
def products_counts(self): | |
'''devuelve la cantidad''' | |
products_counts = {} | |
for sell in self: | |
products_counts[sell.product] = products_counts\ | |
.get(sell.product, 0) + sell.cant | |
for product, count in products_counts.items(): | |
yield ProductCount(product, count) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment