class ProductVariantApi {

	private static final Logger LOGGER = LoggerFactory.getLogger(ProductVariantApi.class);

	@Autowired
	private ProductVariantFacade productVariantFacade;

	@Inject
	private UserFacade userFacade;

	@ResponseStatus(HttpStatus.CREATED)
	@PostMapping(value = { "/private/product/{productId}/variant" })
	@ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"),
		@ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") })
	public @ResponseBody Entity create(
			@Valid @RequestBody PersistableProductVariant variant, 
			@PathVariable Long productId,
			@ApiIgnore MerchantStore merchantStore, 
			@ApiIgnore Language language) {

		String authenticatedUser = userFacade.authenticatedUser();
		if (authenticatedUser == null) {
			throw new UnauthorizedException();
		}

		userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN,
				Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()));

		Long id = productVariantFacade.create(variant, productId, merchantStore, language);
		return new Entity(id);
		
	}


	@ResponseStatus(HttpStatus.OK)
	@PutMapping(value = { "/private/product/{id}/variant/{variantId}" })
	@ApiOperation(httpMethod = "PUT", value = "Update product variant", notes = "", produces = "application/json", response = Void.class)
	public @ResponseBody void update(@PathVariable Long id, @PathVariable Long variantId,
			@Valid @RequestBody PersistableProductVariant variant, @ApiIgnore MerchantStore merchantStore,
			@ApiIgnore Language language) {<FILL_FUNCTION_BODY>}

	@ResponseStatus(HttpStatus.OK)
	@GetMapping(value = { "/private/product/{id}/variant/{sku}/unique" }, produces = "application/json")
	@ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"),
			@ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") })
	@ApiOperation(httpMethod = "GET", value = "Check if option set code already exists", notes = "", response = EntityExists.class)
	public @ResponseBody ResponseEntity<EntityExists> exists(
			@PathVariable Long id, 
			@PathVariable String sku,
			@ApiIgnore MerchantStore merchantStore, 
			@ApiIgnore Language language) {

		String authenticatedUser = userFacade.authenticatedUser();
		if (authenticatedUser == null) {
			throw new UnauthorizedException();
		}

		userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN,
				Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()));

		boolean exist = productVariantFacade.exists(sku, merchantStore, id, language);
		return new ResponseEntity<EntityExists>(new EntityExists(exist), HttpStatus.OK);

	}

	@GetMapping(value = "/private/product/{id}/variant/{variantId}", produces = "application/json")
	@ApiOperation(httpMethod = "GET", value = "Get a productVariant by id", notes = "For administration and shop purpose. Specifying ?merchant is required otherwise it falls back to DEFAULT")
	@ApiResponses(value = {
			@ApiResponse(code = 200, message = "Single product found", response = ReadableProductVariant.class) })
	@ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"),
			@ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") })
	public @ResponseBody ReadableProductVariant get(
			@PathVariable final Long id, 
			@PathVariable Long variantId,
			@RequestParam(value = "lang", required = false) String lang, 
			@ApiIgnore MerchantStore merchantStore,
			@ApiIgnore Language language) throws Exception {

		return productVariantFacade.get(variantId, id, merchantStore, language);

	}

	@ResponseStatus(HttpStatus.OK)
	@RequestMapping(value = { "/private/product/{id}/variants" }, method = RequestMethod.GET)
	@ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"),
			@ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") })
	public @ResponseBody ReadableEntityList<ReadableProductVariant> list(@PathVariable final Long id,
			@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language,
			@RequestParam(value = "page", required = false, defaultValue = "0") Integer page,
			@RequestParam(value = "count", required = false, defaultValue = "10") Integer count) {

		return productVariantFacade.list(id, merchantStore, language, page, count);

	}
	
	@ResponseStatus(HttpStatus.OK)
	@RequestMapping(value = { "/private/product/{id}/variant/{variantId}" }, method = RequestMethod.DELETE)
	@ApiImplicitParams({ 
		@ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"),
			@ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") })
	public void delete(
			@PathVariable Long id,
			@PathVariable Long variantId,
			@ApiIgnore MerchantStore merchantStore,
			@ApiIgnore Language language) {

		productVariantFacade.delete(variantId, id, merchantStore);


	}
	
	
	/**
	
	@ResponseStatus(HttpStatus.CREATED)
	@RequestMapping(value = { "/private/product/{id}/{variantId}/image" }, method = RequestMethod.POST)
	@ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"),
			@ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") })
	public void addvariantImage(
			@PathVariable Long id,
			@RequestParam(name = "file", required = true) MultipartFile file, 
			@ApiIgnore MerchantStore merchantStore,
			@ApiIgnore Language language, 
			HttpServletRequest request, 
			HttpServletResponse response) {

		//productOptionFacade.addOptionValueImage(file, id, merchantStore, language);


	}
	
	**/
	
	

}


		String authenticatedUser = userFacade.authenticatedUser();
		if (authenticatedUser == null) {
			throw new UnauthorizedException();
		}

		userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN,
				Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()));

		productVariantFacade.update(variantId, variant, id, merchantStore, language);
	
<no_super_class>