Quantity of all Products returns same value after OnClick

Viewed 28

To keep things short:

  1. I have multiple products, where you can increment and decrement their value(qnty) inside the cart and after Submitting, a receipt is generated based on the cart Items.

  2. So the Problem is whenever I try to slide the submit, the qnty of the first product I added to cart is assigned to every product, Like

• Apple: 1

• Mango: 5

• Orange: 11

Above is how it should be like

• Apple: 11

• Mango: 11

• Orange: 11

This is the result I am getting, Note: The Result is from new to old

  1. Secondary issue is that whenever I try to write any value inside the textfield and click submit, the value still doesn't get updated!

The Code consists of 2 files:

  1. Parent File
import 'package:ambica_medico/component/result/productcart.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_email_sender/flutter_email_sender.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:whatsapp_unilink/whatsapp_unilink.dart';
import '../../component/buttons/c_button.dart';
import '../../constant.dart';
 
class Cart extends StatefulWidget {
  const Cart({Key? key}) : super(key: key);
 
  @override
  State<Cart> createState() => _CartState();
}
 
class _CartState extends State<Cart> {
  final FirebaseAuth auth = FirebaseAuth.instance;
 
  Stream<QuerySnapshot> _getData() => FirebaseFirestore.instance
      .collection('Users')
      .doc(auth.currentUser?.uid)
      .collection('Carts')
      .snapshots();
 
  String _text = '';
 
  String? product;
  String? qnty;
  String? mail;
  String? name;
  String? address;
  String? dln;
  String? gst;
 
  DateTime now = DateTime.now();
 
  String? stringToSend;
 
  TextEditingController _controller = TextEditingController();
 
  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _controller.dispose();
  }
 
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<dynamic>(
        stream: _getData(),
        builder: (context, snapshot) {
          final tilesList = <Widget>[];
 
          if (snapshot.hasData) {
            snapshot.data.docs.forEach((value) {
              _controller =
                  TextEditingController(text: value.data()['SIB'].toString());
 
              final productTile = Procart(
                pname: value.data()['Product'],
                subtitle: value.data()['MRP'],
                keyo: value.id,
                controller: _controller, sib: value.data()['OSIB'], tis: value.data()['TIS'],
              );
 
              if (_text.isEmpty) {
                tilesList.add(productTile);
              } else {
                if (value
                    .data()['Product']
                    .toUpperCase()
                    .contains(_text.toUpperCase())) {
                  tilesList.add(productTile);
                }
              }
 
              print(_controller.text); //Returns 5,1
            });
 
            return SafeArea(
              child: Scaffold(
                resizeToAvoidBottomInset: false,
                appBar: AppBar(
                  leading: Padding(
                    padding: const EdgeInsets.only(left: 20.0, top: 10),
                    child: IconButton(
                      icon: const Icon(
                        Icons.arrow_back_ios_new_rounded,
                        color: Colors.black,
                        size: 20,
                      ),
                      onPressed: () {
                        Navigator.pop(context);
                      },
                    ),
                  ),
                  backgroundColor: const Color(0xFFf5f3f7),
                  elevation: 0,
                ),
                body: GestureDetector(
                  onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
                  child: Container(
                    decoration: kImageBackground.copyWith(),
                    height: MediaQuery.of(context).size.height,
                    child: Stack(children: [
                      Column(
                        children: [
                          SingleChildScrollView(
                            child: Padding(
                              padding: const EdgeInsets.only(
                                  left: 24.0, right: 24.0, top: 40),
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.stretch,
                                mainAxisAlignment: MainAxisAlignment.start,
                                children: [
                                  const Text(
                                    'The Cart',
                                    style: TextStyle(
                                      fontSize: 40,
                                      fontFamily: 'ProductSans',
                                      fontWeight: FontWeight.bold,
                                      color: Colors.black,
                                    ),
                                  ),
                                  Padding(
                                    padding:
                                        const EdgeInsets.only(top: 50, bottom: 50),
                                    child: Container(
                                      decoration: BoxDecoration(
                                        borderRadius: BorderRadius.circular(20),
                                        color: Colors.white,
                                        boxShadow: const [
                                          BoxShadow(
                                            color: Color(0x261B1B1A),
                                            blurRadius: 50.0,
                                            spreadRadius: 0,
                                            offset: Offset(0.0, 30.0),
                                          ),
                                        ],
                                      ),
                                      height: 70,
                                      child: Center(
                                        child: TextField(
                                          onChanged: (value) {
                                            setState(() {
                                              _text = value;
                                            });
                                          },
                                          keyboardType: TextInputType.text,
                                          decoration: kDecorS.copyWith(
                                            hintText: 'Search Products',
                                          ),
                                          style: const TextStyle(
                                            fontFamily: 'ProductSans',
                                            fontSize: 18,
                                            fontWeight: FontWeight.w400,
                                            color: Color(0xff0f1511),
                                          ),
                                        ),
                                      ),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                          SizedBox(
                            height: MediaQuery.of(context).size.height * 0.55,
                            child: ListView(
                              shrinkWrap: true,
                              physics: const BouncingScrollPhysics(),
                              children: tilesList,
                            ),
                          ),
                        ],
                      ),
                      Positioned(
                        bottom: 0,
                        child: SingleChildScrollView(
                          physics: const NeverScrollableScrollPhysics(),
                          child: Align(
                            alignment: Alignment.bottomCenter,
                            child: Container(
                              width: MediaQuery.of(context).size.width,
                              decoration: const BoxDecoration(
                                borderRadius: BorderRadius.only(
                                  topLeft: Radius.circular(42.0),
                                  topRight: Radius.circular(42.0),
                                ),
                                color: Colors.white,
                              ),
                              child: Padding(
                                padding: const EdgeInsets.only(top: 20),
                                child: Column(
                                  children: [
                                    const Padding(
                                      padding:
                                          EdgeInsets.only(bottom: 10.0),
                                      child: Center(
                                        child: Text(
                                          'Check and then click below to',
                                          style: TextStyle(
                                            fontSize: 14,
                                            fontFamily: 'ProductSans',
                                            fontWeight: FontWeight.bold,
                                            color: Colors.black,
                                          ),
                                        ),
                                      ),
                                    ),
                                    Cbutton(
                                      text: 'Send Order',
                                      onPressed: () async {
                                        String message = "";
                                        DateTime date = DateTime(
                                            now.year, now.month, now.day);
 
                                        await FirebaseFirestore.instance
                                            .collection('Users')
                                            .doc(auth.currentUser?.uid)
                                            .get()
                                            .then((value) => {
                                                  name = value.data()!['name'],
                                                  address =
                                                      value.data()!['address'],
                                                  dln = value.data()!['dln'],
                                                  gst = value.data()!['gst'],
                                                });
 
                                        await snapshot.data.docs.forEach((value) {
                                          product = value.data()['Product'];
                                          qnty = _controller.text; //returns only 1
                                          message += '- $product = $qnty \n';
                                        });
 
                                        final Email email = Email(
                                          body:
                                              "From:- \n\nName: $name\n\nAddress: $address\n\nDrug License No:- $dln\n\nGST No:- $gst\n\nDate:- $date \n\nDear sir,\nPlease dispatch my following order earliest possible through\n $message \n\nThanks & Regards,\n$name",
                                          subject: 'Order Detail',
                                          recipients: ['abc03@gmail.com'],
                                          isHTML: false,
                                        );
 
                                        final link = WhatsAppUnilink(
                                          phoneNumber: '+91 1234567890',
                                          text:
                                          "From:- \n\nName: $name\n\nAddress: $address\n\nDrug License No:- $dln\n\nGST No:- $gst\n\nDate:- $date \n\nDear sir,\nPlease dispatch my following order earliest possible through\n $message \n\nThanks & Regards,\n$name",
                                        );
 
                                        await FlutterEmailSender.send(email);
 
                                        final url = Uri.parse('$link');
 
                                        await launchUrl(url, mode: LaunchMode.externalApplication,);
 
                                      },
                                      icon: const Icon(
                                        Icons.send_rounded,
                                        color: Colors.black,
                                        size: 20,
                                      ),
                                      color: const Color(0xff0f1511),
                                    ),
                                  ],
                                ),
                              ),
                            ),
                          ),
                        ),
                      )
                    ]),
                  ),
                ),
              ),
            );
          } else {
            return const Center(
              child: CircularProgressIndicator(),
            );
          }
        });
  }
}

The main logic of printing the receipt for a product is:

await snapshot.data.docs
                                            .forEach((value) async {
                                          product = value.data()['Product'];
                                          qnty = _controller.text;
                                          message += '- $product = $qnty \n';
                                        });
  1. Child File
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
 
 
class Procart extends StatefulWidget {
  final String pname;
  final String subtitle;
  final String keyo;
  final String sib;
  final String tis;
  final TextEditingController controller;
 
  const Procart(
      {Key? key,
        required this.pname,
        required this.subtitle,
        required this.keyo, required this.controller, required this.sib, required this.tis})
      : super(key: key);
 
  @override
  State<Procart> createState() => _ProcartState();
}
 
class _ProcartState extends State<Procart> {
 
  final FirebaseAuth auth = FirebaseAuth.instance;
 
  late TextEditingController controller = widget.controller;
 
  sub() {
    controller.text =
        (int.parse(controller.text) - 1).toString();
  }
 
  add() {
    controller.text =
        (int.parse(controller.text) + 1).toString();
  }
 
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
      child: Padding(
          padding: const EdgeInsets.only(bottom: 10),
          child: Slidable(
              key: Key(widget.keyo),
              endActionPane: ActionPane(motion: const ScrollMotion(), children: [
                SlidableAction(
                  // An action can be bigger than the others.
                  onPressed: (value) {
                    FirebaseFirestore.instance
                        .collection('Users')
                        .doc(auth.currentUser?.uid)
                        .collection('Carts')
                        .doc(widget.keyo)
                        .delete();
                  },
                  backgroundColor: const Color(0xFFD16464),
                  foregroundColor: Colors.white,
                  icon: Icons.clear_rounded,
                ),
              ]),
              child: Padding(
                padding: const EdgeInsets.only(left: 28.0, right: 28.0),
                child: Container(
                  decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(10)
                  ),
                  child: Padding(
                    padding: const EdgeInsets.all(12.0),
                    child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          SizedBox(
                            width: MediaQuery.of(context).size.width * 0.4,
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Text(
                                  widget.pname,
                                  style: const TextStyle(
                                    fontFamily: 'Satoshi',
                                    fontSize: 16,
                                    fontWeight: FontWeight.bold,
                                    color: Color(0xff0f1511),
                                  ),
                                ),
                                Text(
                                  '${widget.subtitle} | ${widget.sib} x ${widget.tis}',
                                  style: const TextStyle(
                                    fontFamily: 'Satoshi',
                                    fontSize: 12,
                                    fontWeight: FontWeight.normal,
                                    color: Color(0xff0f1511),
                                  ),
                                ),
                              ],
                            ),
                          ),
                          Row(
                            children: [
                              CircleAvatar(
                                radius: 16,
                                backgroundColor: const Color(0xff1b1b1b),
                                child: IconButton(
                                  iconSize: 13,
                                  icon: const Icon(
                                    Icons.remove,
                                    color: Colors.white,
                                  ),
                                  onPressed: () {
                                      if (int.parse(controller.text) >
                                          int.parse(widget.sib)) {
                                        sub();
                                      }
                                  },
                                ),
                              ),
                              SizedBox(
                                width: 80,
                                child: TextField(
                                  textAlign: TextAlign.center,
                                  decoration: const InputDecoration(
                                    border: InputBorder.none,
                                    contentPadding: EdgeInsets.only(left: 6, right: 6),
                                  ),
                                  controller: controller,
                                  keyboardType: TextInputType.number,
                                  style: const TextStyle(
                                    fontFamily: 'Satoshi',
                                    fontSize: 16.0,
                                    fontWeight: FontWeight.bold,
                                    color: Color(0xff0f1511),
                                  ),
                                ),
                              ),
                              CircleAvatar(
                                radius: 16,
                                backgroundColor: const Color(0x33bababa),
                                child: IconButton(
                                  iconSize: 13,
                                  icon: const Icon(
                                    Icons.add,
                                    color: Color(0xff1b1b1b),
                                  ),
                                  onPressed: () {
                                    add();
                                  },
                                ),
                              ),
                            ],
                          ),
                        ]),
                  ),
                ),
              ))),
    );
  }
}

For more info I have attached Screenshots below:

A Huge Thank you to anyone who helps me in solving this!

In-app SS

When Reciept is generated

0 Answers
Related