You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Todos los cambios dentro de la VALIDATIONS en archivo ProductValidation.js:
constcalculateCalories=(fats,proteins,carbohydrates)=>{fats=parseFloat(fats)proteins=parseFloat(proteins)carbohydrates=parseFloat(carbohydrates)constcalories=9*fats+4*proteins+4*carbohydratesif(calories>1000||fats+proteins+carbohydrates!==100){returnfalse}else{returntrue}}module.exports={create: ()=>{return[
...
check('fats').custom((value,{ req })=>{returncalculateCalories(value,req.body.proteins,req.body.carbohydrates)}).withMessage('Un alimento no puede superar las 1000 calorias por cada 100 gramos.')]},update: ()=>{return[
...
check('fats').custom((value,{ req })=>{returncalculateCalories(value,req.body.proteins,req.body.carbohydrates)}).withMessage('Un alimento no puede superar las 1000 calorias por cada 100 gramos.')]}}
En CONTROLLERS no se realiza ningún cambio.
Examen Junio - Mañana:
Todos los cambios dentro de MODELS en archivo restaurant.js:
Todos los cambios dentro de VALIDATIONS en archivo RestaurantValidation.js:
constpromotedRestaurant=async(ownerId,isPromoted)=>{letruleBroken=falseif(isPromoted===true){try{constownerRestaurants=awaitRestaurant.findAll({where: {userId: ownerId,promoted: true}})if(isPromoted&&ownerRestaurants.lenght>0){ruleBroken=true}}catch(error){ruleBroken=true}}returnruleBroken ? Promise.reject(newError('You can only promote one restaurant at a time')) : Promise.resolve()}module.exports={create: ()=>{return[
...
check('promoted').custom((value,{ req })=>{returnpromotedRestaurant(req.user.id,value)}).withMessage('You cant promote more than one restaurant at the same time.')]},update: ()=>{return[
...
check('promoted').custom((value,{ req })=>{returnpromotedRestaurant(req.user.id,value)}).withMessage('You cant promote more than one restaurant at the same time.')]}}
Todos los cambios dentro de CONTROLLERS en archivo RestaurantController.js:
exports.show=asyncfunction(req,res){// Only returns PUBLIC information of restaurantstry{constrestaurant=awaitRestaurant.findByPk(req.params.restaurantId,{attributes: {exclude: ['userId']},include: [{model: Product,as: 'products',order: [['promoted','DESC']],//ESTOS SON LOS CAMBIOSinclude: {model: ProductCategory,as: 'productCategory'}},{model: RestaurantCategory,as: 'restaurantCategory'}]})res.json(restaurant)}catch(err){res.status(404).send(err)}}
Todos los cambios dentro de SCREENS en archivo CreateProductScreen.js:
exportdefaultfunctionCreateProductScreen({ navigation, route }){const[open,setOpen]=useState(false)const[productCategories,setProductCategories]=useState([])const[backendErrors,setBackendErrors]=useState()constinitialProductValues={name: '',description: '',price: 0,order: 0,fats: 0,proteins: 0,carbohydrates: 0,restaurantId: route.params.id,productCategoryId: null,availability: true}constvalidationSchema=yup.object().shape({name: yup.string().max(30,'Name too long').required('Name is required'),price: yup.number().positive('Please provide a positive price value').required('Price is required'),order: yup.number().positive('Please provide a positive cost value').integer('Please provide an integer cost value'),// Solutionfats: yup.number().positive('Please provide a positive cost value').max(100,'The values must be lower or equal than 100'),proteins: yup.number().positive('Please provide a positive cost value').max(100,'The values must be lower or equal than 100'),carbohydrates: yup.number().positive('Please provide a positive cost value').max(100,'The values must be lower or equal than 100')})useEffect(()=>{
...
fetchProductCategories()},[])constpickImage=async(onSuccess)=>{
...
}constcreateProduct=async(values)=>{setBackendErrors([])try{console.log(values)constcreatedProduct=awaitcreate(values)showMessage({message: `Product ${createdProduct.name} succesfully created`,type: 'success',style: flashStyle,titleStyle: flashTextStyle})navigation.navigate('RestaurantDetailScreen',{id: route.params.id,dirty: true})}catch(error){console.log(error)setBackendErrors(error.errors)}}return(<FormikvalidationSchema={validationSchema}initialValues={initialProductValues}onSubmit={createProduct}>{({ handleSubmit, setFieldValue, values })=>(<ScrollView><Viewstyle={{alignItems: 'center'}}><Viewstyle={{width: '60%'}}><InputItemname='name'label='Name:'/><InputItemname='description'label='Description:'/><InputItemname='price'label='Price:'/><InputItemname='order'label='Order/position to be rendered:'/>{/* Solution */}<InputItemname='fats'label='Fats:'/><InputItemname='proteins'label='Proteins:'/><InputItemname='carbohydrates'label='Carbohydrates:'/><DropDownPickeropen={open}value={values.productCategoryId}items={productCategories}setOpen={setOpen}onSelectItem={item=>{setFieldValue('productCategoryId',item.value)}}setItems={setProductCategories}placeholder="Select the product category"containerStyle={{height: 40,marginTop: 20,marginBottom: 20}}style={{backgroundColor: brandBackground}}dropDownStyle={{backgroundColor: '#fafafa'}}/><TextRegular>Is it available?</TextRegular><SwitchtrackColor={{false: brandSecondary,true: brandPrimary}}thumbColor={values.availability ? brandSecondary : '#f4f3f4'}// onValueChange={toggleSwitch}value={values.availability}style={styles.switch}onValueChange={value=>setFieldValue('availability',value)}/><PressableonPress={()=>pickImage(asyncresult=>{awaitsetFieldValue('image',result)})}style={styles.imagePicker}><TextRegular>Product image: </TextRegular><Imagestyle={styles.image}source={values.image ? {uri: values.image.uri} : defaultProduct}/></Pressable>{backendErrors&&backendErrors.map((error,index)=><TextErrorkey={index}>{error.msg}</TextError>)}<PressableonPress={handleSubmit}style={({ pressed })=>[{backgroundColor: pressed
? brandPrimaryTap
: brandPrimary},styles.button]}><TextRegulartextStyle={styles.text}>
Create product
</TextRegular></Pressable></View></View></ScrollView>)}</Formik>)}conststyles=StyleSheet.create({
...
})
Todos los cambios dentro de SCREENS en archivo RestaurantDetailScreen.js: