A煤n no tienes acceso a esta clase

Crea una cuenta y contin煤a viendo este curso

脫rdenes de compra

20/27
Recursos

Aportes 10

Preguntas 2

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

Hecho!

Les dejo el c贸digo de order.model, orders.router, order.schema y order.service:
.
order.model
.

const ORDER_TABLE = 'orders';

const OrderSchema = {
	id: {
		allowNull: false,
		autoIncrement: true,
		primaryKey: true,
		type: DataTypes.INTEGER,
	},
	customerId: {
		field: 'customer_id',
		allowNull: false,
		type: DataTypes.INTEGER,
		References: {
			model: CUSTOMER_TABLE,
			key: 'id',
		},
		onUpdate: 'CASCADE',
		onDelete: 'SET NULL',
	},
	createdAt: {
		allowNull: false,
		type: DataTypes.DATE,
		field: 'created_at',
		defaultValue: Sequelize.NOW,
	},
};

class Order extends Model {
	static associate(models) {
		this.belongsTo(models.Customer, {
			as: 'customer',
		});
	}

	static config(sequelize) {
		return {
			sequelize,
			tableName: ORDER_TABLE,
			modelName: 'Order',
			timestamps: false,
		};
	}
}

module.exports = { Order, OrderSchema, ORDER_TABLE };

.
orders.router
.

const express = require('express');

const OrderService = require('../services/order.service');
const validatorHandler = require('../middlewares/validator.handler');
const {
	getOrderSchema,
	createOrderSchema,
} = require('../schemas/order.schema');

const router = express.Router();
const service = new OrderService();

router.get(
	'/:id',
	validatorHandler(getOrderSchema, 'params'),
	async (req, res, next) => {
		try {
			const { id } = req.params;
			const order = await service.findOne(id);
			res.json(order);
		} catch (error) {
			next(error);
		}
	}
);

router.post(
	'/',
	validatorHandler(createOrderSchema, 'body'),
	async (req, res, next) => {
		try {
			const body = req.body;
			const newOrder = await service.create(body);
			res.status(201).json({ newOrder });
		} catch (error) {
			next(error);
		}
	}
);

module.exports = router;

.
order.service
.

const boom = require('@hapi/boom');

const { models } = require('./../libs/sequelize');

class OrderService {
	constructor() {
	}

	async create(data) {
		const newOrder = await models.Order.create(data);
		return newOrder;
	}

	async find() {
		return [];
	}

	async findOne(id) {
		const order = await models.Order.findByPk(id, {
			include: [
				{
					association: 'customer',
					include: ['user'],
				},
			],
		});
		return order;
	}

	async update(id, changes) {
		return {
			id,
			changes,
		};
	}

	async delete(id) {
		return { id };
	}
}

module.exports = OrderService;

.
order.schema
.

const Joi = require('joi');

const id = Joi.number().integer()
const customerId = Joi.number().integer();


const getOrderSchema = Joi.object({
	id: id.required(),
})

const createOrderSchema = Joi.object({
	customerId: customerId.required(),
});

module.exports = {
	getOrderSchema,
	createOrderSchema
}

Otra forma de sintaxis que permite hacer lo mismo, pero que habilita opciones para hacer un poco mas complejas las consultas.

Con esta forma de sintaxis podemos agregar elementos como: attributes para seleccionar los campos que deseamos del objeto y no todos, where para filtrar el contenido, order para ordenar, entre otros que pueden ver en la documentaci贸n.

Una nota importante es que el al铆as debe llamarse igual que el atributo que obtendr谩 el objeto definido en el esquema del modelo.

const data = await models.Profile.findByPk(id, {
  include: [
    { 
      model: models.User, 
      as: 'user',
      attributes: ['id', 'email']
    },
    { 
      model: models.ProfileCourse, 
      as: 'profiles_courses', 
      attributes: ['id'],
      include: [
        { 
          model: models.Course, 
          as: 'course', 
          attributes: ['name'],
          where: { name: 'Frontend JavaScript' }
        }
      ]
    }
  ]
});

Un error me hizo revertir la migracion de tabla orders, configure mal en el index de models una linea por copiar y pegar

Order.init(OrderSchema, Product.config(sequelize));

ese error no me dejaba hacer el post a la tabla ordenes ya que qued贸 mal configurada

Eso de que devuelva la info relacionada esta hermoso!

Les comparto el model y schema con el campo status

const ORDER_TABLE = 'orders';

const OrderSchema = {
  id: {
    allowNull: false,
    autoIncrement: true,
    primaryKey: true,
    type: DataTypes.INTEGER
  },
  customerId: {
    field: 'customer_id',
    allowNull: true,
    type: DataTypes.INTEGER,
    references: {
      model: CUSTOMER_TABLE,
      key: 'id'
    },
    onUpdate: 'CASCADE',
    onDelete: 'SET NULL'
  },
  status: {
    allowNull: false,
    type: DataTypes.STRING,
    defaultValue: 'paid',
    validate: {
      isIn: [['paid', 'shipped', 'delivered']]
    }
  },
  createdAt: {
    allowNull: false,
    type: DataTypes.DATE,
    field: 'created_at',
    defaultValue: Sequelize.NOW
  }
}

class Order extends Model {
  static associate(models){
    this.belongsTo(models.Customer, {
      as: 'customer',
    })
  }
  static config(sequelize){
    return{
      sequelize,
      tableName: ORDER_TABLE,
      modelName: 'Order',
      timestamps: false,
    }
  }
}

module.exports = { Order, OrderSchema, ORDER_TABLE };
const Joi = require('joi');

const id = Joi.number().integer();
const customerId = Joi.number().integer();
const status = Joi.string().valid('paid', 'shipped', 'delivered')

const getOrderSchema = Joi.object({
  id: id.required(),
});

const createOrderSchema = Joi.object({
  customerId: customerId.required(),
  status: status.required()
});

const updateOrderSchema = Joi.object({
  customerId,
  status
});

module.exports = { getOrderSchema, createOrderSchema, updateOrderSchema };

Reto de agregar un status a las ordenes
Para este reto creo que pueden haber distintas soluciones pero siempre habra la mejor en cuanto a rendimiento por lo que si sientes que tienes una buena soluci贸n para este reto o sabes que mi c贸digo puede ser optimizado sientete libre de comentar y aconsejar para aprender todos 馃槂.
.
.
Modelo de orders
Lo primero que hay que hacer es agregar el status al modelo de orders, a continuaci贸n dejo el c贸digo.
En este caso el valor lo defini como un integer debidoa que quiero que sean n煤meros y dependiendo el n煤mero representar un status u otro, m谩s adelante mostrare eso m谩s detalladamente.

const OrderSchema = {
  id: {
    allowNull: false,
    primaryKey: true,
    autoIncrement: true,
    type: DataTypes.INTEGER
  },
  status: {
    allowNull: false,
    type: DataTypes.INTEGER,
    defaultValue: 0
  },
  customerId: {
    field: 'customer_id',
    allowNull: false,
    type: DataTypes.INTEGER,
    references: {
      model: CUSTOMER_TABLE,
      key: 'id'
    },
    onUpdate: 'CASCADE',
    onDelete: 'SET NULL'
  },
  createdAt: {
    field: 'created_at',
    allowNull: false,
    type: DataTypes.DATE,
    defaultValue: Sequelize.NOW
  }
}

class Order extends Model {
  static associate(models) {
    this.belongsTo(models.Customer, {
        as: 'customer'
      })
  }

  static config(sequelize) {
    return {
      sequelize,
      tableName: ORDER_TABLE,
      modelName: 'Order',
      timestamps: false
    }
  }
}

Generar migraci贸n para la nueva columna del modelo

'use strict';

const { ORDER_TABLE, OrderSchema } = require('../models/order.model')

module.exports = {
  async up (queryInterface) {
    await queryInterface.addColumn(ORDER_TABLE, 'status', OrderSchema.status)
  },

  async down (queryInterface) {
    await queryInterface.removeColumn(ORDER_TABLE, 'status')
  }
};

Agregar el status al schema para validarlo
.
Algo que considero muy importante es no olvidar agregar el status a nuestro validador de datos con el schema de joi.

const joi = require('joi');

const id = joi.number().integer();
const customerId = joi.number().integer();
const status = joi.number().integer();

const getOrderSchema = joi.object({
  id: id.required()
})

const createOrderSchema = joi.object({
  customerId: customerId.required(),
  status
})

const updateOrderSchema = joi.object({
  id: id.required(),
  customerId,
  status
})

module.exports = {
  getOrderSchema,
  createOrderSchema,
  updateOrderSchema
}

Obtener el status
Obtener el status es una tarea muy simple y sencilla, lo que debemos hacer es tomar una calculadora y sacar la distancia de la luna al sol y del sol a la tierra con ello podr茅mos establecer la formula para nuestros estatus鈥
No, solo era broma jajaja鈥 Ahora simplemente vamos al servicio de las ordenes y con un switch seleccionamos que status tendr谩 cada orden, todo esto dentro del metodo find y findOne. En mi caso solo lo hice en el find.

  async find() {
    const orders = await models.Order.findAll({
      include: [
        {
          association: 'customer',
          include: ['user']
        }
      ]
    })

    orders.forEach(order => {
      switch(order.status) {
        case 0:
          order.status = 'Preparando el producto'
          break;

        case 1:
          order.status = 'Producto en camino'
          break;

        case 2:
          order.status = 'Producto entegado :)'
          break;
      }
    })

    return orders
  }

crazy ese findone 馃枛

De momento solo se realiz贸 la relaci贸n ordenes de compra, clientes y usuarios.

Un producto puede pertenecer a muchas ordenes de compra, y una orden de compra puede tener muchos productos.

Cuando se tiene una relaci贸n muchos a muchos, por detr谩s se tiene una tabla ternaria. En BD se usa una join table, una clase intermedia que conecta dos tablas con relaci贸n muchos a muchos.

Para este caso se va requerir la tabla orders (ordenes de compra), esta estar谩 ligada a un cliente. La join table serian los items que estar谩n ligados a una orden y producto.

La tabla order tiene que ser una relaci贸n uno a muchos ya que un cliente puede tener muchas ordenes y una orden un cliente.

Para tener un anidamiento 鈥渕谩s profundo鈥, se debe especificar de la siguiente manera en el servicio order.service.js (order 鈫 customer 鈫 user):

async findOne(id) {
    const order = await models.Order.findByPk(id, {
      include: [
        {
          association: 'customer',
          include: ['user'],
        },
      ],
    });
    return order;
  }

Con esto hecho, el resultado del request mostrar谩 los datos del cliente y del usuario. Es decir, estamos diciendo que customer traiga su propia asociaci贸n la cual es user.