Example #1
0
        public async Task <AddReceiptResult> AddReceiptAsync([NotNull] ReceiptRequestDto requestDto)
        {
            if (requestDto == null)
            {
                throw new ArgumentNullException(nameof(requestDto));
            }
            var hash = _HashCalculator.Calculate(requestDto);

            var isExistsInFnsDb = await _FnsService.IsReceiptExists(requestDto.FiscalNumber, requestDto.FiscalDocument, requestDto.FiscalSign, requestDto.Time,
                                                                    requestDto.Sum);

            if (!isExistsInFnsDb.ReceiptExists)
            {
                throw new ReceiptNotExistsInFns("Receipt is not exists in FNS db");
            }

            CheckReceiptSDK.Results.Document doc = null;

            int tries = 6;

            while (tries > 0)
            {
                tries--;

                var result = await _FnsService.ReceiveAsync(requestDto.FiscalNumber, requestDto.FiscalDocument, requestDto.FiscalSign);

                doc = result.Document;
                if (result.StatusCode == HttpStatusCode.PaymentRequired)
                {
                    throw new OverLimitException("Free FNS requests limit exceeded. Login as another user or pay to FNS.");
                }

                if (result.StatusCode != HttpStatusCode.Accepted &&
                    result.StatusCode != HttpStatusCode.OK &&
                    result.StatusCode != HttpStatusCode.Created)
                {
                    throw new Exception($"Failed to receive fns data. Status Code: {result.StatusCode}; Details: \'{result.Message}\'");
                }
                if (doc == null && result.StatusCode == HttpStatusCode.Accepted)
                {
                    await Task.Delay(750);

                    continue;
                }

                break;
            }

            //todo вместо этого, реализовать очередь на добавление, что бы сервис сам добавил рецепт, когда фнс станет доступен.
            if (doc == null)
            {
                throw new FnsProbablyUnavailableException("FNS Service currently can be unavailable. Please try later.");
            }

            var receipt = new Receipt
            {
                Hash      = hash,
                Date      = requestDto.Time,
                RawQrData = requestDto.RawQRData,
                //todo после реализации юзеров, получать id реального авторизованного юзера веб-сервиса.
                UserId = 1
            };

            var addedReceipt = await _ReceiptsRepository.AddReceiptAsync(receipt);

            if (addedReceipt == null)
            {
                throw new FailedToAddReceiptException("Failed to add receipt to db");
            }

            var extended = new ReceiptExtended
            {
                ReceiptId     = addedReceipt.ReceiptId,
                Cashier       = doc.Receipt.Cashier,
                StoreName     = doc.Receipt.StoreName,
                RetailAddress = doc.Receipt.RetailPlaceAddress,
                KktRegId      = doc.Receipt.KktRegId,
                ShiftNumber   = doc.Receipt.ShiftNumber.ToString(),
                RetailInn     = doc.Receipt.RetailInn
            };

            var addedExtended = await _ReceiptsRepository.AddExtendedInfoToReceipt(extended);

            if (addedExtended == null)
            {
                _Logger.Log(LogLevel.Error, "Failed to add extended receipt for {receiptId}", extended.ReceiptId);
            }

            var addedItems = new List <Item>();

            foreach (var receiptItem in doc.Receipt.Items)
            {
                var item = new Item()
                {
                    Sum       = receiptItem.Sum,
                    Name      = receiptItem.Name,
                    Price     = receiptItem.Price,
                    Quantity  = receiptItem.Quantity,
                    ReceiptId = addedReceipt.ReceiptId
                };
                var addedItem = await _ItemsRepository.AddItem(item);

                addedItems.Add(addedItem);
            }

            return(new AddReceiptResult
            {
                Id = addedReceipt.ReceiptId,
                Hash = addedReceipt.Hash,
                AddedItemsCount = addedItems.Count,
                RawQRData = requestDto.RawQRData
            });
        }