Merge branch 'pharmacy' of https://gitlab.com/Cloud_Solution/diplomatic-quarter into fatima_merge
Conflicts: android/app/build.gradle lib/config/config.dart lib/pages/pharmacy/profile/profile.dart lib/widgets/pharmacy/product_tile.dartmerge-requests/228/head
commit
16d1f667d4
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
@ -0,0 +1,32 @@
|
||||
class CountryData {
|
||||
int id;
|
||||
String name;
|
||||
String namen;
|
||||
String twoLetterIsoCode;
|
||||
String threeLetterIsoCode;
|
||||
|
||||
CountryData(
|
||||
{this.id,
|
||||
this.name,
|
||||
this.namen,
|
||||
this.twoLetterIsoCode,
|
||||
this.threeLetterIsoCode});
|
||||
|
||||
CountryData.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
name = json['name'];
|
||||
namen = json['namen'];
|
||||
twoLetterIsoCode = json['two_letter_iso_code'];
|
||||
threeLetterIsoCode = json['three_letter_iso_code'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['id'] = this.id;
|
||||
data['name'] = this.name;
|
||||
data['namen'] = this.namen;
|
||||
data['two_letter_iso_code'] = this.twoLetterIsoCode;
|
||||
data['three_letter_iso_code'] = this.threeLetterIsoCode;
|
||||
return data;
|
||||
}
|
||||
}
|
@ -1,24 +1,117 @@
|
||||
|
||||
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
|
||||
import 'package:diplomaticquarterapp/core/enum/viewstate.dart';
|
||||
import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart';
|
||||
import 'package:diplomaticquarterapp/core/model/pharmacies/Country.dart';
|
||||
import 'package:diplomaticquarterapp/services/pharmacy_services/pharmacyAddress_service.dart';
|
||||
import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyAddressesModel.dart';
|
||||
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
|
||||
import 'package:google_maps_place_picker/google_maps_place_picker.dart';
|
||||
import '../../../locator.dart';
|
||||
import '../base_view_model.dart';
|
||||
|
||||
class PharmacyAddressesViewModel extends BaseViewModel {
|
||||
PharmacyAddressService _pharmacyAddressService = locator<PharmacyAddressService>();
|
||||
List<PharmacyAddressesModel> get address => _pharmacyAddressService.address;
|
||||
PharmacyAddressService _pharmacyAddressService =
|
||||
locator<PharmacyAddressService>();
|
||||
|
||||
List<Addresses> get addresses => _pharmacyAddressService.addresses;
|
||||
|
||||
int get selectedAddressIndex => _pharmacyAddressService.selectedAddressIndex;
|
||||
|
||||
CountryData get country => _pharmacyAddressService.country;
|
||||
|
||||
Future getAddress(address) async {
|
||||
setSelectedAddressIndex(int index) {
|
||||
_pharmacyAddressService.selectedAddressIndex = index;
|
||||
}
|
||||
|
||||
Future getAddressesList() async {
|
||||
setState(ViewState.Busy);
|
||||
await _pharmacyAddressService.getAddress(address);
|
||||
await _pharmacyAddressService.getAddresses();
|
||||
if (_pharmacyAddressService.hasError) {
|
||||
error = _pharmacyAddressService.error;
|
||||
setState(ViewState.Error);
|
||||
} else {
|
||||
print(address.length);
|
||||
setState(ViewState.Idle);
|
||||
}
|
||||
}
|
||||
|
||||
/* Future getCountries(String countryName) async {
|
||||
setState(ViewState.Busy);
|
||||
await _pharmacyAddressService.getCountries(countryName);
|
||||
if (_pharmacyAddressService.hasError) {
|
||||
error = _pharmacyAddressService.error;
|
||||
// setState(ViewState.Error);
|
||||
} else {
|
||||
// setState(ViewState.Idle);
|
||||
}
|
||||
}*/
|
||||
|
||||
Future addEditAddress(PickResult value, Addresses editedAddress) async {
|
||||
setState(ViewState.Busy);
|
||||
|
||||
Addresses sendingAddress;
|
||||
|
||||
if (editedAddress == null) {
|
||||
sendingAddress = Addresses();
|
||||
sendingAddress.id = "0";
|
||||
sendingAddress.firstName = user.firstName;
|
||||
sendingAddress.lastName = user.lastName;
|
||||
sendingAddress.email = user.emailAddress;
|
||||
sendingAddress.company = null;
|
||||
} else {
|
||||
sendingAddress = editedAddress;
|
||||
}
|
||||
value.addressComponents.forEach((element) {
|
||||
if (element.types.contains("country")) {
|
||||
sendingAddress.country = element.longName;
|
||||
}
|
||||
if (element.types.contains("administrative_area_level_1")) {
|
||||
sendingAddress.city = element.longName;
|
||||
}
|
||||
if (element.types.contains("postal_code")) {
|
||||
sendingAddress.zipPostalCode = element.longName;
|
||||
}
|
||||
if (element.types.contains("administrative_area_level_2")) {
|
||||
sendingAddress.province = element.longName;
|
||||
}
|
||||
});
|
||||
sendingAddress.latLong = value.geometry.location.toString();
|
||||
|
||||
await _pharmacyAddressService.getCountries(sendingAddress.country);
|
||||
sendingAddress.countryId = country.id;
|
||||
sendingAddress.stateProvinceId = null;
|
||||
sendingAddress.address1 = value.formattedAddress;
|
||||
sendingAddress.address2 = "";
|
||||
sendingAddress.phoneNumber = user.mobileNumber;
|
||||
sendingAddress.faxNumber = user.faxNumber;
|
||||
sendingAddress.customerAttributes = "";
|
||||
sendingAddress.createdOnUtc = DateTime.now().toString();
|
||||
|
||||
if (editedAddress == null) {
|
||||
await _pharmacyAddressService.addCustomerAddress(sendingAddress);
|
||||
} else {
|
||||
await _pharmacyAddressService.editCustomerAddress(sendingAddress);
|
||||
}
|
||||
|
||||
if (_pharmacyAddressService.hasError) {
|
||||
error = _pharmacyAddressService.error;
|
||||
setState(ViewState.Error);
|
||||
} else {
|
||||
setState(ViewState.Idle);
|
||||
}
|
||||
}
|
||||
|
||||
Future deleteAddresses(Addresses sendingAddress) async {
|
||||
setState(ViewState.Busy);
|
||||
await _pharmacyAddressService.deleteCustomerAddress(sendingAddress);
|
||||
if (_pharmacyAddressService.hasError) {
|
||||
error = _pharmacyAddressService.error;
|
||||
setState(ViewState.Error);
|
||||
} else {
|
||||
setState(ViewState.Idle);
|
||||
}
|
||||
}
|
||||
|
||||
Future saveSelectedAddressLocally(Addresses selectedAddress) async {
|
||||
await sharedPref.setObject(PHARMACY_SELECTED_ADDRESS, selectedAddress);
|
||||
}
|
||||
}
|
@ -0,0 +1,924 @@
|
||||
// To parse this JSON data, do
|
||||
//
|
||||
// final shoppingCart = shoppingCartFromJson(jsonString);
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
ShoppingCart shoppingCartFromJson(String str) => ShoppingCart.fromJson(json.decode(str));
|
||||
|
||||
String shoppingCartToJson(ShoppingCart data) => json.encode(data.toJson());
|
||||
|
||||
class ShoppingCart {
|
||||
ShoppingCart({
|
||||
this.itemCount,
|
||||
this.quantityCount,
|
||||
this.subtotal,
|
||||
this.subtotalWithVat,
|
||||
this.subtotalVatAmount,
|
||||
this.subtotalVatRate,
|
||||
this.shoppingCarts,
|
||||
});
|
||||
|
||||
int itemCount;
|
||||
int quantityCount;
|
||||
double subtotal;
|
||||
double subtotalWithVat;
|
||||
double subtotalVatAmount;
|
||||
int subtotalVatRate;
|
||||
List<ShoppingCartElement> shoppingCarts;
|
||||
|
||||
factory ShoppingCart.fromJson(Map<String, dynamic> json) => ShoppingCart(
|
||||
itemCount: json["item_count"],
|
||||
quantityCount: json["quantity_count"],
|
||||
subtotal: json["subtotal"].toDouble(),
|
||||
subtotalWithVat: json["subtotal_with_vat"].toDouble(),
|
||||
subtotalVatAmount: json["subtotal_vat_amount"].toDouble(),
|
||||
subtotalVatRate: json["subtotal_vat_rate"],
|
||||
shoppingCarts: List<ShoppingCartElement>.from(json["shopping_carts"].map((x) => ShoppingCartElement.fromJson(x))),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"item_count": itemCount,
|
||||
"quantity_count": quantityCount,
|
||||
"subtotal": subtotal,
|
||||
"subtotal_with_vat": subtotalWithVat,
|
||||
"subtotal_vat_amount": subtotalVatAmount,
|
||||
"subtotal_vat_rate": subtotalVatRate,
|
||||
"shopping_carts": List<dynamic>.from(shoppingCarts.map((x) => x.toJson())),
|
||||
};
|
||||
}
|
||||
|
||||
class ShoppingCartElement {
|
||||
ShoppingCartElement({
|
||||
this.languageId,
|
||||
this.id,
|
||||
this.productAttributes,
|
||||
this.customerEnteredPrice,
|
||||
this.quantity,
|
||||
this.discountAmountInclTax,
|
||||
this.subtotal,
|
||||
this.subtotalWithVat,
|
||||
this.subtotalVatAmount,
|
||||
this.subtotalVatRate,
|
||||
this.currency,
|
||||
this.currencyn,
|
||||
this.rentalStartDateUtc,
|
||||
this.rentalEndDateUtc,
|
||||
this.createdOnUtc,
|
||||
this.updatedOnUtc,
|
||||
this.shoppingCartType,
|
||||
this.productId,
|
||||
this.product,
|
||||
this.customerId,
|
||||
this.customer,
|
||||
});
|
||||
|
||||
int languageId;
|
||||
String id;
|
||||
List<dynamic> productAttributes;
|
||||
int customerEnteredPrice;
|
||||
int quantity;
|
||||
dynamic discountAmountInclTax;
|
||||
String subtotal;
|
||||
String subtotalWithVat;
|
||||
String subtotalVatAmount;
|
||||
String subtotalVatRate;
|
||||
String currency;
|
||||
String currencyn;
|
||||
dynamic rentalStartDateUtc;
|
||||
dynamic rentalEndDateUtc;
|
||||
DateTime createdOnUtc;
|
||||
DateTime updatedOnUtc;
|
||||
String shoppingCartType;
|
||||
int productId;
|
||||
Product product;
|
||||
int customerId;
|
||||
Customer customer;
|
||||
|
||||
factory ShoppingCartElement.fromJson(Map<String, dynamic> json) => ShoppingCartElement(
|
||||
languageId: json["language_id"],
|
||||
id: json["id"],
|
||||
productAttributes: List<dynamic>.from(json["product_attributes"].map((x) => x)),
|
||||
customerEnteredPrice: json["customer_entered_price"],
|
||||
quantity: json["quantity"],
|
||||
discountAmountInclTax: json["discount_amount_incl_tax"],
|
||||
subtotal: json["subtotal"],
|
||||
subtotalWithVat: json["subtotal_with_vat"],
|
||||
subtotalVatAmount: json["subtotal_vat_amount"],
|
||||
subtotalVatRate: json["subtotal_vat_rate"],
|
||||
currency: json["currency"],
|
||||
currencyn: json["currencyn"],
|
||||
rentalStartDateUtc: json["rental_start_date_utc"],
|
||||
rentalEndDateUtc: json["rental_end_date_utc"],
|
||||
createdOnUtc: DateTime.parse(json["created_on_utc"]),
|
||||
updatedOnUtc: DateTime.parse(json["updated_on_utc"]),
|
||||
shoppingCartType: json["shopping_cart_type"],
|
||||
productId: json["product_id"],
|
||||
product: Product.fromJson(json["product"]),
|
||||
customerId: json["customer_id"],
|
||||
customer: Customer.fromJson(json["customer"]),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"language_id": languageId,
|
||||
"id": id,
|
||||
"product_attributes": List<dynamic>.from(productAttributes.map((x) => x)),
|
||||
"customer_entered_price": customerEnteredPrice,
|
||||
"quantity": quantity,
|
||||
"discount_amount_incl_tax": discountAmountInclTax,
|
||||
"subtotal": subtotal,
|
||||
"subtotal_with_vat": subtotalWithVat,
|
||||
"subtotal_vat_amount": subtotalVatAmount,
|
||||
"subtotal_vat_rate": subtotalVatRate,
|
||||
"currency": currency,
|
||||
"currencyn": currencyn,
|
||||
"rental_start_date_utc": rentalStartDateUtc,
|
||||
"rental_end_date_utc": rentalEndDateUtc,
|
||||
"created_on_utc": createdOnUtc.toIso8601String(),
|
||||
"updated_on_utc": updatedOnUtc.toIso8601String(),
|
||||
"shopping_cart_type": shoppingCartType,
|
||||
"product_id": productId,
|
||||
"product": product.toJson(),
|
||||
"customer_id": customerId,
|
||||
"customer": customer.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
class Customer {
|
||||
Customer({
|
||||
this.billingAddress,
|
||||
this.shippingAddress,
|
||||
this.addresses,
|
||||
this.id,
|
||||
this.username,
|
||||
this.email,
|
||||
this.firstName,
|
||||
this.lastName,
|
||||
this.languageId,
|
||||
this.adminComment,
|
||||
this.isTaxExempt,
|
||||
this.hasShoppingCartItems,
|
||||
this.active,
|
||||
this.deleted,
|
||||
this.isSystemAccount,
|
||||
this.systemName,
|
||||
this.lastIpAddress,
|
||||
this.createdOnUtc,
|
||||
this.lastLoginDateUtc,
|
||||
this.lastActivityDateUtc,
|
||||
this.registeredInStoreId,
|
||||
this.roleIds,
|
||||
});
|
||||
|
||||
Address billingAddress;
|
||||
Address shippingAddress;
|
||||
List<Address> addresses;
|
||||
String id;
|
||||
String username;
|
||||
String email;
|
||||
dynamic firstName;
|
||||
dynamic lastName;
|
||||
dynamic languageId;
|
||||
dynamic adminComment;
|
||||
bool isTaxExempt;
|
||||
bool hasShoppingCartItems;
|
||||
bool active;
|
||||
bool deleted;
|
||||
bool isSystemAccount;
|
||||
dynamic systemName;
|
||||
String lastIpAddress;
|
||||
DateTime createdOnUtc;
|
||||
DateTime lastLoginDateUtc;
|
||||
DateTime lastActivityDateUtc;
|
||||
int registeredInStoreId;
|
||||
List<dynamic> roleIds;
|
||||
|
||||
factory Customer.fromJson(Map<String, dynamic> json) => Customer(
|
||||
billingAddress: Address.fromJson(json["billing_address"]),
|
||||
shippingAddress: Address.fromJson(json["shipping_address"]),
|
||||
addresses: List<Address>.from(json["addresses"].map((x) => Address.fromJson(x))),
|
||||
id: json["id"],
|
||||
username: json["username"],
|
||||
email: json["email"],
|
||||
firstName: json["first_name"],
|
||||
lastName: json["last_name"],
|
||||
languageId: json["language_id"],
|
||||
adminComment: json["admin_comment"],
|
||||
isTaxExempt: json["is_tax_exempt"],
|
||||
hasShoppingCartItems: json["has_shopping_cart_items"],
|
||||
active: json["active"],
|
||||
deleted: json["deleted"],
|
||||
isSystemAccount: json["is_system_account"],
|
||||
systemName: json["system_name"],
|
||||
lastIpAddress: json["last_ip_address"],
|
||||
createdOnUtc: DateTime.parse(json["created_on_utc"]),
|
||||
lastLoginDateUtc: DateTime.parse(json["last_login_date_utc"]),
|
||||
lastActivityDateUtc: DateTime.parse(json["last_activity_date_utc"]),
|
||||
registeredInStoreId: json["registered_in_store_id"],
|
||||
roleIds: List<dynamic>.from(json["role_ids"].map((x) => x)),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"billing_address": billingAddress.toJson(),
|
||||
"shipping_address": shippingAddress.toJson(),
|
||||
"addresses": List<dynamic>.from(addresses.map((x) => x.toJson())),
|
||||
"id": id,
|
||||
"username": username,
|
||||
"email": email,
|
||||
"first_name": firstName,
|
||||
"last_name": lastName,
|
||||
"language_id": languageId,
|
||||
"admin_comment": adminComment,
|
||||
"is_tax_exempt": isTaxExempt,
|
||||
"has_shopping_cart_items": hasShoppingCartItems,
|
||||
"active": active,
|
||||
"deleted": deleted,
|
||||
"is_system_account": isSystemAccount,
|
||||
"system_name": systemName,
|
||||
"last_ip_address": lastIpAddress,
|
||||
"created_on_utc": createdOnUtc.toIso8601String(),
|
||||
"last_login_date_utc": lastLoginDateUtc.toIso8601String(),
|
||||
"last_activity_date_utc": lastActivityDateUtc.toIso8601String(),
|
||||
"registered_in_store_id": registeredInStoreId,
|
||||
"role_ids": List<dynamic>.from(roleIds.map((x) => x)),
|
||||
};
|
||||
}
|
||||
|
||||
class Address {
|
||||
Address({
|
||||
this.id,
|
||||
this.firstName,
|
||||
this.lastName,
|
||||
this.email,
|
||||
this.company,
|
||||
this.countryId,
|
||||
this.country,
|
||||
this.stateProvinceId,
|
||||
this.city,
|
||||
this.address1,
|
||||
this.address2,
|
||||
this.zipPostalCode,
|
||||
this.phoneNumber,
|
||||
this.faxNumber,
|
||||
this.customerAttributes,
|
||||
this.createdOnUtc,
|
||||
this.province,
|
||||
this.latLong,
|
||||
});
|
||||
|
||||
String id;
|
||||
FirstName firstName;
|
||||
LastName lastName;
|
||||
Email email;
|
||||
dynamic company;
|
||||
int countryId;
|
||||
Country country;
|
||||
dynamic stateProvinceId;
|
||||
City city;
|
||||
String address1;
|
||||
String address2;
|
||||
String zipPostalCode;
|
||||
String phoneNumber;
|
||||
dynamic faxNumber;
|
||||
String customerAttributes;
|
||||
DateTime createdOnUtc;
|
||||
dynamic province;
|
||||
String latLong;
|
||||
|
||||
factory Address.fromJson(Map<String, dynamic> json) => Address(
|
||||
id: json["id"],
|
||||
firstName: firstNameValues.map[json["first_name"]],
|
||||
lastName: lastNameValues.map[json["last_name"]],
|
||||
email: emailValues.map[json["email"]],
|
||||
company: json["company"],
|
||||
countryId: json["country_id"],
|
||||
country: countryValues.map[json["country"]],
|
||||
stateProvinceId: json["state_province_id"],
|
||||
city: cityValues.map[json["city"]],
|
||||
address1: json["address1"],
|
||||
address2: json["address2"],
|
||||
zipPostalCode: json["zip_postal_code"],
|
||||
phoneNumber: json["phone_number"],
|
||||
faxNumber: json["fax_number"],
|
||||
customerAttributes: json["customer_attributes"],
|
||||
createdOnUtc: DateTime.parse(json["created_on_utc"]),
|
||||
province: json["province"],
|
||||
latLong: json["lat_long"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"first_name": firstNameValues.reverse[firstName],
|
||||
"last_name": lastNameValues.reverse[lastName],
|
||||
"email": emailValues.reverse[email],
|
||||
"company": company,
|
||||
"country_id": countryId,
|
||||
"country": countryValues.reverse[country],
|
||||
"state_province_id": stateProvinceId,
|
||||
"city": cityValues.reverse[city],
|
||||
"address1": address1,
|
||||
"address2": address2,
|
||||
"zip_postal_code": zipPostalCode,
|
||||
"phone_number": phoneNumber,
|
||||
"fax_number": faxNumber,
|
||||
"customer_attributes": customerAttributes,
|
||||
"created_on_utc": createdOnUtc.toIso8601String(),
|
||||
"province": province,
|
||||
"lat_long": latLong,
|
||||
};
|
||||
}
|
||||
|
||||
enum City { CALIFORNIA, RIYADH, AL_OYUN }
|
||||
|
||||
final cityValues = EnumValues({
|
||||
"Al Oyun": City.AL_OYUN,
|
||||
"California": City.CALIFORNIA,
|
||||
"Riyadh": City.RIYADH
|
||||
});
|
||||
|
||||
enum Country { UNITED_STATES, SAUDI_ARABIA }
|
||||
|
||||
final countryValues = EnumValues({
|
||||
"Saudi Arabia": Country.SAUDI_ARABIA,
|
||||
"United States": Country.UNITED_STATES
|
||||
});
|
||||
|
||||
enum Email { TAMER_FANASHEH_GMAIL_COM, TAMER_DASDASDAS_GMAIL_COM, TAMER_F_CLOUDSOLUTION_SA_COM }
|
||||
|
||||
final emailValues = EnumValues({
|
||||
"Tamer.dasdasdas@gmail.com": Email.TAMER_DASDASDAS_GMAIL_COM,
|
||||
"Tamer.fanasheh@gmail.com": Email.TAMER_FANASHEH_GMAIL_COM,
|
||||
"Tamer.F@cloudsolution-sa.com": Email.TAMER_F_CLOUDSOLUTION_SA_COM
|
||||
});
|
||||
|
||||
enum FirstName { TAMER, TAMER_FANASHEH }
|
||||
|
||||
final firstNameValues = EnumValues({
|
||||
"TAMER": FirstName.TAMER,
|
||||
"TAMER FANASHEH": FirstName.TAMER_FANASHEH
|
||||
});
|
||||
|
||||
enum LastName { FANASHEH, MUSA }
|
||||
|
||||
final lastNameValues = EnumValues({
|
||||
"FANASHEH": LastName.FANASHEH,
|
||||
"MUSA": LastName.MUSA
|
||||
});
|
||||
|
||||
class Product {
|
||||
Product({
|
||||
this.id,
|
||||
this.visibleIndividually,
|
||||
this.name,
|
||||
this.namen,
|
||||
this.localizedNames,
|
||||
this.shortDescription,
|
||||
this.shortDescriptionn,
|
||||
this.fullDescription,
|
||||
this.fullDescriptionn,
|
||||
this.markasNew,
|
||||
this.showOnHomePage,
|
||||
this.metaKeywords,
|
||||
this.metaDescription,
|
||||
this.metaTitle,
|
||||
this.allowCustomerReviews,
|
||||
this.approvedRatingSum,
|
||||
this.notApprovedRatingSum,
|
||||
this.approvedTotalReviews,
|
||||
this.notApprovedTotalReviews,
|
||||
this.sku,
|
||||
this.isRx,
|
||||
this.prescriptionRequired,
|
||||
this.rxMessage,
|
||||
this.rxMessagen,
|
||||
this.manufacturerPartNumber,
|
||||
this.gtin,
|
||||
this.isGiftCard,
|
||||
this.requireOtherProducts,
|
||||
this.automaticallyAddRequiredProducts,
|
||||
this.isDownload,
|
||||
this.unlimitedDownloads,
|
||||
this.maxNumberOfDownloads,
|
||||
this.downloadExpirationDays,
|
||||
this.hasSampleDownload,
|
||||
this.hasUserAgreement,
|
||||
this.isRecurring,
|
||||
this.recurringCycleLength,
|
||||
this.recurringTotalCycles,
|
||||
this.isRental,
|
||||
this.rentalPriceLength,
|
||||
this.isShipEnabled,
|
||||
this.isFreeShipping,
|
||||
this.shipSeparately,
|
||||
this.additionalShippingCharge,
|
||||
this.isTaxExempt,
|
||||
this.isTelecommunicationsOrBroadcastingOrElectronicServices,
|
||||
this.useMultipleWarehouses,
|
||||
this.manageInventoryMethodId,
|
||||
this.stockQuantity,
|
||||
this.stockAvailability,
|
||||
this.stockAvailabilityn,
|
||||
this.displayStockAvailability,
|
||||
this.displayStockQuantity,
|
||||
this.minStockQuantity,
|
||||
this.notifyAdminForQuantityBelow,
|
||||
this.allowBackInStockSubscriptions,
|
||||
this.orderMinimumQuantity,
|
||||
this.orderMaximumQuantity,
|
||||
this.allowedQuantities,
|
||||
this.allowAddingOnlyExistingAttributeCombinations,
|
||||
this.disableBuyButton,
|
||||
this.disableWishlistButton,
|
||||
this.availableForPreOrder,
|
||||
this.preOrderAvailabilityStartDateTimeUtc,
|
||||
this.callForPrice,
|
||||
this.price,
|
||||
this.oldPrice,
|
||||
this.productCost,
|
||||
this.specialPrice,
|
||||
this.specialPriceStartDateTimeUtc,
|
||||
this.specialPriceEndDateTimeUtc,
|
||||
this.customerEntersPrice,
|
||||
this.minimumCustomerEnteredPrice,
|
||||
this.maximumCustomerEnteredPrice,
|
||||
this.basepriceEnabled,
|
||||
this.basepriceAmount,
|
||||
this.basepriceBaseAmount,
|
||||
this.hasTierPrices,
|
||||
this.hasDiscountsApplied,
|
||||
this.discountName,
|
||||
this.discountNamen,
|
||||
this.discountDescription,
|
||||
this.discountDescriptionn,
|
||||
this.discountPercentage,
|
||||
this.currency,
|
||||
this.currencyn,
|
||||
this.weight,
|
||||
this.length,
|
||||
this.width,
|
||||
this.height,
|
||||
this.availableStartDateTimeUtc,
|
||||
this.availableEndDateTimeUtc,
|
||||
this.displayOrder,
|
||||
this.published,
|
||||
this.deleted,
|
||||
this.createdOnUtc,
|
||||
this.updatedOnUtc,
|
||||
this.productType,
|
||||
this.parentGroupedProductId,
|
||||
this.roleIds,
|
||||
this.discountIds,
|
||||
this.storeIds,
|
||||
this.manufacturerIds,
|
||||
this.reviews,
|
||||
this.images,
|
||||
this.attributes,
|
||||
this.specifications,
|
||||
this.associatedProductIds,
|
||||
this.tags,
|
||||
this.vendorId,
|
||||
this.seName,
|
||||
});
|
||||
|
||||
String id;
|
||||
bool visibleIndividually;
|
||||
String name;
|
||||
String namen;
|
||||
List<LocalizedName> localizedNames;
|
||||
String shortDescription;
|
||||
String shortDescriptionn;
|
||||
String fullDescription;
|
||||
String fullDescriptionn;
|
||||
bool markasNew;
|
||||
bool showOnHomePage;
|
||||
String metaKeywords;
|
||||
String metaDescription;
|
||||
String metaTitle;
|
||||
bool allowCustomerReviews;
|
||||
int approvedRatingSum;
|
||||
int notApprovedRatingSum;
|
||||
int approvedTotalReviews;
|
||||
int notApprovedTotalReviews;
|
||||
String sku;
|
||||
bool isRx;
|
||||
bool prescriptionRequired;
|
||||
dynamic rxMessage;
|
||||
dynamic rxMessagen;
|
||||
dynamic manufacturerPartNumber;
|
||||
dynamic gtin;
|
||||
bool isGiftCard;
|
||||
bool requireOtherProducts;
|
||||
bool automaticallyAddRequiredProducts;
|
||||
bool isDownload;
|
||||
bool unlimitedDownloads;
|
||||
int maxNumberOfDownloads;
|
||||
dynamic downloadExpirationDays;
|
||||
bool hasSampleDownload;
|
||||
bool hasUserAgreement;
|
||||
bool isRecurring;
|
||||
int recurringCycleLength;
|
||||
int recurringTotalCycles;
|
||||
bool isRental;
|
||||
int rentalPriceLength;
|
||||
bool isShipEnabled;
|
||||
bool isFreeShipping;
|
||||
bool shipSeparately;
|
||||
int additionalShippingCharge;
|
||||
bool isTaxExempt;
|
||||
bool isTelecommunicationsOrBroadcastingOrElectronicServices;
|
||||
bool useMultipleWarehouses;
|
||||
int manageInventoryMethodId;
|
||||
int stockQuantity;
|
||||
String stockAvailability;
|
||||
String stockAvailabilityn;
|
||||
bool displayStockAvailability;
|
||||
bool displayStockQuantity;
|
||||
int minStockQuantity;
|
||||
int notifyAdminForQuantityBelow;
|
||||
bool allowBackInStockSubscriptions;
|
||||
int orderMinimumQuantity;
|
||||
int orderMaximumQuantity;
|
||||
dynamic allowedQuantities;
|
||||
bool allowAddingOnlyExistingAttributeCombinations;
|
||||
bool disableBuyButton;
|
||||
bool disableWishlistButton;
|
||||
bool availableForPreOrder;
|
||||
dynamic preOrderAvailabilityStartDateTimeUtc;
|
||||
bool callForPrice;
|
||||
double price;
|
||||
int oldPrice;
|
||||
double productCost;
|
||||
dynamic specialPrice;
|
||||
dynamic specialPriceStartDateTimeUtc;
|
||||
dynamic specialPriceEndDateTimeUtc;
|
||||
bool customerEntersPrice;
|
||||
int minimumCustomerEnteredPrice;
|
||||
int maximumCustomerEnteredPrice;
|
||||
bool basepriceEnabled;
|
||||
int basepriceAmount;
|
||||
int basepriceBaseAmount;
|
||||
bool hasTierPrices;
|
||||
bool hasDiscountsApplied;
|
||||
dynamic discountName;
|
||||
dynamic discountNamen;
|
||||
dynamic discountDescription;
|
||||
dynamic discountDescriptionn;
|
||||
dynamic discountPercentage;
|
||||
String currency;
|
||||
String currencyn;
|
||||
double weight;
|
||||
int length;
|
||||
int width;
|
||||
int height;
|
||||
dynamic availableStartDateTimeUtc;
|
||||
dynamic availableEndDateTimeUtc;
|
||||
int displayOrder;
|
||||
bool published;
|
||||
bool deleted;
|
||||
DateTime createdOnUtc;
|
||||
DateTime updatedOnUtc;
|
||||
String productType;
|
||||
int parentGroupedProductId;
|
||||
List<dynamic> roleIds;
|
||||
List<dynamic> discountIds;
|
||||
List<dynamic> storeIds;
|
||||
List<int> manufacturerIds;
|
||||
List<dynamic> reviews;
|
||||
List<Image> images;
|
||||
List<dynamic> attributes;
|
||||
List<Specification> specifications;
|
||||
List<dynamic> associatedProductIds;
|
||||
List<dynamic> tags;
|
||||
int vendorId;
|
||||
String seName;
|
||||
|
||||
factory Product.fromJson(Map<String, dynamic> json) => Product(
|
||||
id: json["id"],
|
||||
visibleIndividually: json["visible_individually"],
|
||||
name: json["name"],
|
||||
namen: json["namen"],
|
||||
localizedNames: List<LocalizedName>.from(json["localized_names"].map((x) => LocalizedName.fromJson(x))),
|
||||
shortDescription: json["short_description"],
|
||||
shortDescriptionn: json["short_descriptionn"],
|
||||
fullDescription: json["full_description"],
|
||||
fullDescriptionn: json["full_descriptionn"],
|
||||
markasNew: json["markas_new"],
|
||||
showOnHomePage: json["show_on_home_page"],
|
||||
metaKeywords: json["meta_keywords"] == null ? null : json["meta_keywords"],
|
||||
metaDescription: json["meta_description"] == null ? null : json["meta_description"],
|
||||
metaTitle: json["meta_title"] == null ? null : json["meta_title"],
|
||||
allowCustomerReviews: json["allow_customer_reviews"],
|
||||
approvedRatingSum: json["approved_rating_sum"],
|
||||
notApprovedRatingSum: json["not_approved_rating_sum"],
|
||||
approvedTotalReviews: json["approved_total_reviews"],
|
||||
notApprovedTotalReviews: json["not_approved_total_reviews"],
|
||||
sku: json["sku"],
|
||||
isRx: json["is_rx"],
|
||||
prescriptionRequired: json["prescription_required"],
|
||||
rxMessage: json["rx_message"],
|
||||
rxMessagen: json["rx_messagen"],
|
||||
manufacturerPartNumber: json["manufacturer_part_number"],
|
||||
gtin: json["gtin"],
|
||||
isGiftCard: json["is_gift_card"],
|
||||
requireOtherProducts: json["require_other_products"],
|
||||
automaticallyAddRequiredProducts: json["automatically_add_required_products"],
|
||||
isDownload: json["is_download"],
|
||||
unlimitedDownloads: json["unlimited_downloads"],
|
||||
maxNumberOfDownloads: json["max_number_of_downloads"],
|
||||
downloadExpirationDays: json["download_expiration_days"],
|
||||
hasSampleDownload: json["has_sample_download"],
|
||||
hasUserAgreement: json["has_user_agreement"],
|
||||
isRecurring: json["is_recurring"],
|
||||
recurringCycleLength: json["recurring_cycle_length"],
|
||||
recurringTotalCycles: json["recurring_total_cycles"],
|
||||
isRental: json["is_rental"],
|
||||
rentalPriceLength: json["rental_price_length"],
|
||||
isShipEnabled: json["is_ship_enabled"],
|
||||
isFreeShipping: json["is_free_shipping"],
|
||||
shipSeparately: json["ship_separately"],
|
||||
additionalShippingCharge: json["additional_shipping_charge"],
|
||||
isTaxExempt: json["is_tax_exempt"],
|
||||
isTelecommunicationsOrBroadcastingOrElectronicServices: json["is_telecommunications_or_broadcasting_or_electronic_services"],
|
||||
useMultipleWarehouses: json["use_multiple_warehouses"],
|
||||
manageInventoryMethodId: json["manage_inventory_method_id"],
|
||||
stockQuantity: json["stock_quantity"],
|
||||
stockAvailability: json["stock_availability"],
|
||||
stockAvailabilityn: json["stock_availabilityn"],
|
||||
displayStockAvailability: json["display_stock_availability"],
|
||||
displayStockQuantity: json["display_stock_quantity"],
|
||||
minStockQuantity: json["min_stock_quantity"],
|
||||
notifyAdminForQuantityBelow: json["notify_admin_for_quantity_below"],
|
||||
allowBackInStockSubscriptions: json["allow_back_in_stock_subscriptions"],
|
||||
orderMinimumQuantity: json["order_minimum_quantity"],
|
||||
orderMaximumQuantity: json["order_maximum_quantity"],
|
||||
allowedQuantities: json["allowed_quantities"],
|
||||
allowAddingOnlyExistingAttributeCombinations: json["allow_adding_only_existing_attribute_combinations"],
|
||||
disableBuyButton: json["disable_buy_button"],
|
||||
disableWishlistButton: json["disable_wishlist_button"],
|
||||
availableForPreOrder: json["available_for_pre_order"],
|
||||
preOrderAvailabilityStartDateTimeUtc: json["pre_order_availability_start_date_time_utc"],
|
||||
callForPrice: json["call_for_price"],
|
||||
price: json["price"].toDouble(),
|
||||
oldPrice: json["old_price"],
|
||||
productCost: json["product_cost"].toDouble(),
|
||||
specialPrice: json["special_price"],
|
||||
specialPriceStartDateTimeUtc: json["special_price_start_date_time_utc"],
|
||||
specialPriceEndDateTimeUtc: json["special_price_end_date_time_utc"],
|
||||
customerEntersPrice: json["customer_enters_price"],
|
||||
minimumCustomerEnteredPrice: json["minimum_customer_entered_price"],
|
||||
maximumCustomerEnteredPrice: json["maximum_customer_entered_price"],
|
||||
basepriceEnabled: json["baseprice_enabled"],
|
||||
basepriceAmount: json["baseprice_amount"],
|
||||
basepriceBaseAmount: json["baseprice_base_amount"],
|
||||
hasTierPrices: json["has_tier_prices"],
|
||||
hasDiscountsApplied: json["has_discounts_applied"],
|
||||
discountName: json["discount_name"],
|
||||
discountNamen: json["discount_namen"],
|
||||
discountDescription: json["discount_description"],
|
||||
discountDescriptionn: json["discount_Descriptionn"],
|
||||
discountPercentage: json["discount_percentage"],
|
||||
currency: json["currency"],
|
||||
currencyn: json["currencyn"],
|
||||
weight: json["weight"].toDouble(),
|
||||
length: json["length"],
|
||||
width: json["width"],
|
||||
height: json["height"],
|
||||
availableStartDateTimeUtc: json["available_start_date_time_utc"],
|
||||
availableEndDateTimeUtc: json["available_end_date_time_utc"],
|
||||
displayOrder: json["display_order"],
|
||||
published: json["published"],
|
||||
deleted: json["deleted"],
|
||||
createdOnUtc: DateTime.parse(json["created_on_utc"]),
|
||||
updatedOnUtc: DateTime.parse(json["updated_on_utc"]),
|
||||
productType: json["product_type"],
|
||||
parentGroupedProductId: json["parent_grouped_product_id"],
|
||||
roleIds: List<dynamic>.from(json["role_ids"].map((x) => x)),
|
||||
discountIds: List<dynamic>.from(json["discount_ids"].map((x) => x)),
|
||||
storeIds: List<dynamic>.from(json["store_ids"].map((x) => x)),
|
||||
manufacturerIds: List<int>.from(json["manufacturer_ids"].map((x) => x)),
|
||||
reviews: List<dynamic>.from(json["reviews"].map((x) => x)),
|
||||
images: List<Image>.from(json["images"].map((x) => Image.fromJson(x))),
|
||||
attributes: List<dynamic>.from(json["attributes"].map((x) => x)),
|
||||
specifications: List<Specification>.from(json["specifications"].map((x) => Specification.fromJson(x))),
|
||||
associatedProductIds: List<dynamic>.from(json["associated_product_ids"].map((x) => x)),
|
||||
tags: List<dynamic>.from(json["tags"].map((x) => x)),
|
||||
vendorId: json["vendor_id"],
|
||||
seName: json["se_name"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"visible_individually": visibleIndividually,
|
||||
"name": name,
|
||||
"namen": namen,
|
||||
"localized_names": List<dynamic>.from(localizedNames.map((x) => x.toJson())),
|
||||
"short_description": shortDescription,
|
||||
"short_descriptionn": shortDescriptionn,
|
||||
"full_description": fullDescription,
|
||||
"full_descriptionn": fullDescriptionn,
|
||||
"markas_new": markasNew,
|
||||
"show_on_home_page": showOnHomePage,
|
||||
"meta_keywords": metaKeywords == null ? null : metaKeywords,
|
||||
"meta_description": metaDescription == null ? null : metaDescription,
|
||||
"meta_title": metaTitle == null ? null : metaTitle,
|
||||
"allow_customer_reviews": allowCustomerReviews,
|
||||
"approved_rating_sum": approvedRatingSum,
|
||||
"not_approved_rating_sum": notApprovedRatingSum,
|
||||
"approved_total_reviews": approvedTotalReviews,
|
||||
"not_approved_total_reviews": notApprovedTotalReviews,
|
||||
"sku": sku,
|
||||
"is_rx": isRx,
|
||||
"prescription_required": prescriptionRequired,
|
||||
"rx_message": rxMessage,
|
||||
"rx_messagen": rxMessagen,
|
||||
"manufacturer_part_number": manufacturerPartNumber,
|
||||
"gtin": gtin,
|
||||
"is_gift_card": isGiftCard,
|
||||
"require_other_products": requireOtherProducts,
|
||||
"automatically_add_required_products": automaticallyAddRequiredProducts,
|
||||
"is_download": isDownload,
|
||||
"unlimited_downloads": unlimitedDownloads,
|
||||
"max_number_of_downloads": maxNumberOfDownloads,
|
||||
"download_expiration_days": downloadExpirationDays,
|
||||
"has_sample_download": hasSampleDownload,
|
||||
"has_user_agreement": hasUserAgreement,
|
||||
"is_recurring": isRecurring,
|
||||
"recurring_cycle_length": recurringCycleLength,
|
||||
"recurring_total_cycles": recurringTotalCycles,
|
||||
"is_rental": isRental,
|
||||
"rental_price_length": rentalPriceLength,
|
||||
"is_ship_enabled": isShipEnabled,
|
||||
"is_free_shipping": isFreeShipping,
|
||||
"ship_separately": shipSeparately,
|
||||
"additional_shipping_charge": additionalShippingCharge,
|
||||
"is_tax_exempt": isTaxExempt,
|
||||
"is_telecommunications_or_broadcasting_or_electronic_services": isTelecommunicationsOrBroadcastingOrElectronicServices,
|
||||
"use_multiple_warehouses": useMultipleWarehouses,
|
||||
"manage_inventory_method_id": manageInventoryMethodId,
|
||||
"stock_quantity": stockQuantity,
|
||||
"stock_availability": stockAvailability,
|
||||
"stock_availabilityn": stockAvailabilityn,
|
||||
"display_stock_availability": displayStockAvailability,
|
||||
"display_stock_quantity": displayStockQuantity,
|
||||
"min_stock_quantity": minStockQuantity,
|
||||
"notify_admin_for_quantity_below": notifyAdminForQuantityBelow,
|
||||
"allow_back_in_stock_subscriptions": allowBackInStockSubscriptions,
|
||||
"order_minimum_quantity": orderMinimumQuantity,
|
||||
"order_maximum_quantity": orderMaximumQuantity,
|
||||
"allowed_quantities": allowedQuantities,
|
||||
"allow_adding_only_existing_attribute_combinations": allowAddingOnlyExistingAttributeCombinations,
|
||||
"disable_buy_button": disableBuyButton,
|
||||
"disable_wishlist_button": disableWishlistButton,
|
||||
"available_for_pre_order": availableForPreOrder,
|
||||
"pre_order_availability_start_date_time_utc": preOrderAvailabilityStartDateTimeUtc,
|
||||
"call_for_price": callForPrice,
|
||||
"price": price,
|
||||
"old_price": oldPrice,
|
||||
"product_cost": productCost,
|
||||
"special_price": specialPrice,
|
||||
"special_price_start_date_time_utc": specialPriceStartDateTimeUtc,
|
||||
"special_price_end_date_time_utc": specialPriceEndDateTimeUtc,
|
||||
"customer_enters_price": customerEntersPrice,
|
||||
"minimum_customer_entered_price": minimumCustomerEnteredPrice,
|
||||
"maximum_customer_entered_price": maximumCustomerEnteredPrice,
|
||||
"baseprice_enabled": basepriceEnabled,
|
||||
"baseprice_amount": basepriceAmount,
|
||||
"baseprice_base_amount": basepriceBaseAmount,
|
||||
"has_tier_prices": hasTierPrices,
|
||||
"has_discounts_applied": hasDiscountsApplied,
|
||||
"discount_name": discountName,
|
||||
"discount_namen": discountNamen,
|
||||
"discount_description": discountDescription,
|
||||
"discount_Descriptionn": discountDescriptionn,
|
||||
"discount_percentage": discountPercentage,
|
||||
"currency": currency,
|
||||
"currencyn": currencyn,
|
||||
"weight": weight,
|
||||
"length": length,
|
||||
"width": width,
|
||||
"height": height,
|
||||
"available_start_date_time_utc": availableStartDateTimeUtc,
|
||||
"available_end_date_time_utc": availableEndDateTimeUtc,
|
||||
"display_order": displayOrder,
|
||||
"published": published,
|
||||
"deleted": deleted,
|
||||
"created_on_utc": createdOnUtc.toIso8601String(),
|
||||
"updated_on_utc": updatedOnUtc.toIso8601String(),
|
||||
"product_type": productType,
|
||||
"parent_grouped_product_id": parentGroupedProductId,
|
||||
"role_ids": List<dynamic>.from(roleIds.map((x) => x)),
|
||||
"discount_ids": List<dynamic>.from(discountIds.map((x) => x)),
|
||||
"store_ids": List<dynamic>.from(storeIds.map((x) => x)),
|
||||
"manufacturer_ids": List<dynamic>.from(manufacturerIds.map((x) => x)),
|
||||
"reviews": List<dynamic>.from(reviews.map((x) => x)),
|
||||
"images": List<dynamic>.from(images.map((x) => x.toJson())),
|
||||
"attributes": List<dynamic>.from(attributes.map((x) => x)),
|
||||
"specifications": List<dynamic>.from(specifications.map((x) => x.toJson())),
|
||||
"associated_product_ids": List<dynamic>.from(associatedProductIds.map((x) => x)),
|
||||
"tags": List<dynamic>.from(tags.map((x) => x)),
|
||||
"vendor_id": vendorId,
|
||||
"se_name": seName,
|
||||
};
|
||||
}
|
||||
|
||||
class Image {
|
||||
Image({
|
||||
this.id,
|
||||
this.position,
|
||||
this.src,
|
||||
this.thumb,
|
||||
this.attachment,
|
||||
});
|
||||
|
||||
int id;
|
||||
int position;
|
||||
String src;
|
||||
String thumb;
|
||||
String attachment;
|
||||
|
||||
factory Image.fromJson(Map<String, dynamic> json) => Image(
|
||||
id: json["id"],
|
||||
position: json["position"],
|
||||
src: json["src"],
|
||||
thumb: json["thumb"],
|
||||
attachment: json["attachment"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"position": position,
|
||||
"src": src,
|
||||
"thumb": thumb,
|
||||
"attachment": attachment,
|
||||
};
|
||||
}
|
||||
|
||||
class LocalizedName {
|
||||
LocalizedName({
|
||||
this.languageId,
|
||||
this.localizedName,
|
||||
});
|
||||
|
||||
int languageId;
|
||||
String localizedName;
|
||||
|
||||
factory LocalizedName.fromJson(Map<String, dynamic> json) => LocalizedName(
|
||||
languageId: json["language_id"],
|
||||
localizedName: json["localized_name"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"language_id": languageId,
|
||||
"localized_name": localizedName,
|
||||
};
|
||||
}
|
||||
|
||||
class Specification {
|
||||
Specification({
|
||||
this.id,
|
||||
this.displayOrder,
|
||||
this.defaultValue,
|
||||
this.defaultValuen,
|
||||
this.name,
|
||||
this.nameN,
|
||||
});
|
||||
|
||||
int id;
|
||||
int displayOrder;
|
||||
String defaultValue;
|
||||
String defaultValuen;
|
||||
String name;
|
||||
String nameN;
|
||||
|
||||
factory Specification.fromJson(Map<String, dynamic> json) => Specification(
|
||||
id: json["id"],
|
||||
displayOrder: json["display_order"],
|
||||
defaultValue: json["default_value"],
|
||||
defaultValuen: json["default_valuen"],
|
||||
name: json["name"],
|
||||
nameN: json["nameN"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"display_order": displayOrder,
|
||||
"default_value": defaultValue,
|
||||
"default_valuen": defaultValuen,
|
||||
"name": name,
|
||||
"nameN": nameN,
|
||||
};
|
||||
}
|
||||
|
||||
class EnumValues<T> {
|
||||
Map<String, T> map;
|
||||
Map<T, String> reverseMap;
|
||||
|
||||
EnumValues(this.map);
|
||||
|
||||
Map<T, String> get reverse {
|
||||
if (reverseMap == null) {
|
||||
reverseMap = map.map((k, v) => new MapEntry(v, k));
|
||||
}
|
||||
return reverseMap;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
// To parse this JSON data, do
|
||||
//
|
||||
// final specificationModel = specificationModelFromJson(jsonString);
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
SpecificationModel specificationModelFromJson(String str) => SpecificationModel.fromJson(json.decode(str));
|
||||
|
||||
String specificationModelToJson(SpecificationModel data) => json.encode(data.toJson());
|
||||
|
||||
class SpecificationModel {
|
||||
SpecificationModel({
|
||||
this.specification,
|
||||
});
|
||||
|
||||
List<Specification> specification;
|
||||
|
||||
factory SpecificationModel.fromJson(Map<String, dynamic> json) => SpecificationModel(
|
||||
specification: List<Specification>.from(json["specification"].map((x) => Specification.fromJson(x))),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"specification": List<dynamic>.from(specification.map((x) => x.toJson())),
|
||||
};
|
||||
}
|
||||
|
||||
class Specification {
|
||||
Specification({
|
||||
this.id,
|
||||
this.displayOrder,
|
||||
this.defaultValue,
|
||||
this.defaultValuen,
|
||||
this.name,
|
||||
this.nameN,
|
||||
});
|
||||
|
||||
int id;
|
||||
int displayOrder;
|
||||
String defaultValue;
|
||||
String defaultValuen;
|
||||
String name;
|
||||
String nameN;
|
||||
|
||||
factory Specification.fromJson(Map<String, dynamic> json) => Specification(
|
||||
id: json["id"],
|
||||
displayOrder: json["display_order"],
|
||||
defaultValue: json["default_value"],
|
||||
defaultValuen: json["default_valuen"],
|
||||
name: json["name"],
|
||||
nameN: json["nameN"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"display_order": displayOrder,
|
||||
"default_value": defaultValue,
|
||||
"default_valuen": defaultValuen,
|
||||
"name": name,
|
||||
"nameN": nameN,
|
||||
};
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart';
|
||||
|
||||
class CompareList with ChangeNotifier {
|
||||
List<PharmacyProduct> _product = [];
|
||||
|
||||
List<PharmacyProduct> get productListItems => _product;
|
||||
|
||||
void addItem(data) {
|
||||
if (_product.length == 0) {
|
||||
_product.add(data);
|
||||
AppToast.showSuccessToast(message: 'You have added a product to the Compare list');
|
||||
} else {
|
||||
for (int i = 0; i < _product.length; i++) {
|
||||
if (_product.length <= 4 && _product[i].id != data.id) {
|
||||
_product.add(data);
|
||||
AppToast.showSuccessToast(message: 'You have added a product to the Compare list');
|
||||
break;
|
||||
} else if(_product[i].id == data.id){
|
||||
AppToast.showErrorToast(message: 'the item is already in the list');
|
||||
} else if(_product.length == 4){
|
||||
AppToast.showErrorToast(message: 'your compare list is full');
|
||||
}
|
||||
}
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void deleteItem(data) {
|
||||
for (int i = 0; i < _product.length; i++) {
|
||||
if (_product[i].id == data) _product.remove(_product[i]);
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,145 @@
|
||||
import 'package:diplomaticquarterapp/config/size_config.dart';
|
||||
import 'package:diplomaticquarterapp/core/enum/viewstate.dart';
|
||||
import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/brand_view_model.dart';
|
||||
import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart';
|
||||
import 'package:diplomaticquarterapp/pages/base/base_view.dart';
|
||||
import 'package:diplomaticquarterapp/uitl/utils.dart';
|
||||
import 'package:diplomaticquarterapp/widgets/buttons/button.dart';
|
||||
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
|
||||
import 'package:diplomaticquarterapp/widgets/input/text_field.dart';
|
||||
import 'package:diplomaticquarterapp/widgets/others/StarRating.dart';
|
||||
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget.dart';
|
||||
import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SearchBrandsPage extends StatefulWidget {
|
||||
@override
|
||||
_SearchBrandsPageState createState() => _SearchBrandsPageState();
|
||||
}
|
||||
|
||||
class _SearchBrandsPageState extends State<SearchBrandsPage> {
|
||||
final textController = TextEditingController();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
String msg = '';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BaseView<BrandsViewModel>(
|
||||
onModelReady: (model) => model.searchProducts(),
|
||||
builder: (BuildContext context, model, Widget child) =>
|
||||
PharmacyAppScaffold(
|
||||
appBarTitle: 'Search',
|
||||
isBottomBar: false,
|
||||
isShowAppBar: true,
|
||||
backgroundColor: Colors.white,
|
||||
isShowDecPage: false,
|
||||
//baseViewModel: model,
|
||||
body: SingleChildScrollView(
|
||||
child: Container(
|
||||
height: SizeConfig.screenHeight,
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width * 0.79,
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: TextFields(
|
||||
autoFocus: true,
|
||||
hintText: 'Search',
|
||||
fontSize: 19.0,
|
||||
prefixIcon: Icon(Icons.search),
|
||||
inputAction: TextInputAction.search,
|
||||
onSaved: (value) {
|
||||
//searchMedicine(model, context);
|
||||
},
|
||||
onSubmit: (value) {
|
||||
searchMedicine(model, context);
|
||||
msg = 'No Result Found';
|
||||
},
|
||||
controller: textController,
|
||||
validator: (value) {
|
||||
if (value.isEmpty) {
|
||||
return 'please Enter Product Name';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 10.0,
|
||||
),
|
||||
InkWell(
|
||||
child: Texts(
|
||||
'Cancel',
|
||||
fontSize: 17.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
|
||||
// child: Container(
|
||||
// child: Button(
|
||||
// backgroundColor: Colors.green,
|
||||
// loading: model.state == ViewState.BusyLocal,
|
||||
// label: 'Search',
|
||||
// onTap: () {
|
||||
// searchMedicine(model, context);
|
||||
// }),
|
||||
// width: MediaQuery.of(context).size.width * 0.09,
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
model.searchList.length == 0
|
||||
? Container(
|
||||
child: Text(
|
||||
'no data' + model.searchList.length.toString()),
|
||||
)
|
||||
: Expanded(
|
||||
child: Container(
|
||||
child: ListView.builder(
|
||||
itemCount: model.searchList.length,
|
||||
itemBuilder: (BuildContext ctx, index) {
|
||||
return Padding(
|
||||
padding:EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Container(
|
||||
child: Text(
|
||||
model.searchList[index].name,
|
||||
style: TextStyle(fontSize: 20),
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(height: 1, color: Colors.grey)
|
||||
],),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
searchMedicine(model, BuildContext context) {
|
||||
Utils.hideKeyboard(context);
|
||||
if (_formKey.currentState.validate())
|
||||
model.searchProducts(productName: textController.text);
|
||||
}
|
||||
}
|
@ -1,38 +1,102 @@
|
||||
import 'package:diplomaticquarterapp/config/config.dart';
|
||||
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
|
||||
import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart';
|
||||
import 'package:diplomaticquarterapp/core/model/pharmacies/Country.dart';
|
||||
import 'package:diplomaticquarterapp/core/service/base_service.dart';
|
||||
import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
|
||||
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart';
|
||||
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyAddressesModel.dart';
|
||||
|
||||
class PharmacyAddressService extends BaseService {
|
||||
List<Addresses> addresses = List();
|
||||
CountryData country;
|
||||
int selectedAddressIndex = 0;
|
||||
|
||||
class PharmacyAddressService extends BaseService{
|
||||
|
||||
AppSharedPreferences sharedPref = AppSharedPreferences();
|
||||
AppGlobal appGlobal = new AppGlobal();
|
||||
AuthenticatedUser authUser = new AuthenticatedUser();
|
||||
AuthProvider authProvider = new AuthProvider();
|
||||
|
||||
List<PharmacyAddressesModel> get address => address;
|
||||
List<PharmacyAddressesModel> _addressList = List();
|
||||
List<PharmacyAddressesModel> get reviewList => _addressList;
|
||||
String url ="";
|
||||
Future getAddresses() async {
|
||||
var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID);
|
||||
Map<String, String> queryParams = {'fields': 'addresses'};
|
||||
hasError = false;
|
||||
Addresses selectedAddress;
|
||||
try {
|
||||
await baseAppClient.get("$GET_CUSTOMERS_ADDRESSES$customerId",
|
||||
onSuccess: (dynamic response, int statusCode) async {
|
||||
addresses.clear();
|
||||
var savedAddress =
|
||||
await sharedPref.getObject(PHARMACY_SELECTED_ADDRESS);
|
||||
if (savedAddress != null) {
|
||||
selectedAddress = Addresses.fromJson(savedAddress);
|
||||
}
|
||||
int index = 0;
|
||||
response['customers'][0]['addresses'].forEach((item) {
|
||||
Addresses address = Addresses.fromJson(item);
|
||||
if (selectedAddress != null && selectedAddress.id == item["id"]) {
|
||||
selectedAddressIndex = index;
|
||||
}
|
||||
addresses.add(address);
|
||||
index++;
|
||||
});
|
||||
}, onFailure: (String error, int statusCode) {
|
||||
hasError = true;
|
||||
super.error = error;
|
||||
}, queryParams: queryParams);
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
Future getAddress(address) async {
|
||||
print("step 1");
|
||||
Future getCountries(String countryName) async {
|
||||
hasError = false;
|
||||
url =GET_ADDRESS+"272843?fields=addresses";
|
||||
print(url);
|
||||
await baseAppClient.getPharmacy(url,
|
||||
try {
|
||||
await baseAppClient.get("$PHARMACY_GET_COUNTRY",
|
||||
onSuccess: (dynamic response, int statusCode) {
|
||||
_addressList.clear();
|
||||
response['customers'].forEach((item) {
|
||||
_addressList.add(PharmacyAddressesModel.fromJson(item));
|
||||
// countries.clear();
|
||||
response['countries'].forEach((item) {
|
||||
if (CountryData.fromJson(item).name == countryName ||
|
||||
CountryData.fromJson(item).namen == countryName) {
|
||||
country = CountryData.fromJson(item);
|
||||
}
|
||||
// countries.add(CountryData.fromJson(item));
|
||||
});
|
||||
}, onFailure: (String error, int statusCode) {
|
||||
hasError = true;
|
||||
super.error = error;
|
||||
});
|
||||
}}
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
Future addCustomerAddress(Addresses address) async {
|
||||
makeCustomerAddress(address, ADD_CUSTOMER_ADDRESS);
|
||||
}
|
||||
|
||||
Future editCustomerAddress(Addresses address) async {
|
||||
makeCustomerAddress(address, EDIT_CUSTOMER_ADDRESS);
|
||||
}
|
||||
|
||||
Future deleteCustomerAddress(Addresses address) async {
|
||||
makeCustomerAddress(address, DELETE_CUSTOMER_ADDRESS);
|
||||
}
|
||||
|
||||
Future makeCustomerAddress(Addresses address, String url) async {
|
||||
var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID);
|
||||
hasError = false;
|
||||
super.error = "";
|
||||
|
||||
Map<String, dynamic> customerObject = Map();
|
||||
customerObject["addresses"] = [address];
|
||||
customerObject["id"] = customerId;
|
||||
customerObject["email"] = address.email;
|
||||
customerObject["role_ids"] = [3];
|
||||
Map<String, dynamic> body = Map();
|
||||
body["customer"] = customerObject;
|
||||
|
||||
await baseAppClient.post("$url", onSuccess: (response, statusCode) async {
|
||||
addresses.clear();
|
||||
response['customers'][0]['addresses'].forEach((item) {
|
||||
addresses.add(Addresses.fromJson(item));
|
||||
});
|
||||
}, onFailure: (String error, int statusCode) {
|
||||
hasError = true;
|
||||
super.error = error;
|
||||
}, body: body);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,241 @@
|
||||
import 'package:diplomaticquarterapp/config/config.dart';
|
||||
import 'package:diplomaticquarterapp/config/size_config.dart';
|
||||
import 'package:diplomaticquarterapp/config/size_config.dart';
|
||||
import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart';
|
||||
import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart';
|
||||
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
|
||||
import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart';
|
||||
import 'package:diplomaticquarterapp/pages/landing/landing_page.dart';
|
||||
import 'package:diplomaticquarterapp/routes.dart';
|
||||
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
|
||||
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
|
||||
import 'package:diplomaticquarterapp/widgets/others/bottom_bar.dart';
|
||||
import 'package:diplomaticquarterapp/widgets/progress_indicator/app_loader_widget.dart';
|
||||
import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart';
|
||||
import 'package:diplomaticquarterapp/widgets/robo-search/robosearch.dart';
|
||||
import 'package:diplomaticquarterapp/widgets/robo-search/search.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../locator.dart';
|
||||
import 'floating_button_search.dart';
|
||||
import '../progress_indicator/app_loader_widget.dart';
|
||||
import 'arrow_back.dart';
|
||||
import 'network_base_view.dart';
|
||||
import 'not_auh_page.dart';
|
||||
import 'package:diplomaticquarterapp/pages/pharmacies/product_detail.dart';
|
||||
import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart';
|
||||
|
||||
class DetailPageScafold extends StatefulWidget {
|
||||
final String appBarTitle;
|
||||
final Widget body;
|
||||
final Widget bottomSheet;
|
||||
final bool isLoading;
|
||||
final bool isShowAppBar;
|
||||
final bool hasAppBarParam;
|
||||
final BaseViewModel baseViewModel;
|
||||
final bool isBottomBar;
|
||||
final Widget floatingActionButton;
|
||||
final bool isPharmacy;
|
||||
final String title;
|
||||
final String description;
|
||||
final String image;
|
||||
final bool isShowDecPage;
|
||||
final List<String> infoList;
|
||||
final Color backgroundColor;
|
||||
final double preferredSize;
|
||||
final List<Widget> appBarIcons;
|
||||
final PreferredSizeWidget appBarWidget;
|
||||
|
||||
|
||||
DetailPageScafold(
|
||||
{@required this.body,
|
||||
this.appBarTitle = '',
|
||||
this.isLoading = false,
|
||||
this.isShowAppBar = false,
|
||||
this.hasAppBarParam,
|
||||
this.bottomSheet,
|
||||
this.baseViewModel,
|
||||
this.floatingActionButton,
|
||||
this.isPharmacy = false,
|
||||
this.title,
|
||||
this.description,
|
||||
this.isShowDecPage = true,
|
||||
this.isBottomBar,
|
||||
this.backgroundColor,
|
||||
this.preferredSize = 0.0,
|
||||
this.appBarIcons,
|
||||
this.appBarWidget,
|
||||
this.image,
|
||||
this.infoList});
|
||||
|
||||
@override
|
||||
_DetailPageScafoldState createState() => _DetailPageScafoldState();
|
||||
}
|
||||
|
||||
class _DetailPageScafoldState extends State<DetailPageScafold> {
|
||||
AuthenticatedUserObject authenticatedUserObject =
|
||||
locator<AuthenticatedUserObject>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
AppGlobal.context = context;
|
||||
PreferredSizeWidget appBar;
|
||||
|
||||
if (this.widget.appBarWidget == null) {
|
||||
PreferredSizeWidget appBarWidget = AppBarWidget(
|
||||
widget.appBarTitle,
|
||||
widget.appBarIcons,
|
||||
widget.isShowAppBar,
|
||||
isPharmacy: widget.isPharmacy,
|
||||
isShowDecPage: widget.isShowDecPage,
|
||||
image: widget.image,
|
||||
);
|
||||
appBar = widget.preferredSize == 0
|
||||
? appBarWidget
|
||||
: PreferredSize(
|
||||
child: appBarWidget,
|
||||
preferredSize: Size.fromHeight(widget.preferredSize));
|
||||
} else {
|
||||
appBar = this.widget.appBarWidget;
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor:
|
||||
widget.backgroundColor ?? Theme.of(context).scaffoldBackgroundColor,
|
||||
appBar: appBar,
|
||||
body: (!Provider.of<ProjectViewModel>(context, listen: false).isLogin &&
|
||||
widget.isShowDecPage)
|
||||
? NotAutPage(
|
||||
title: widget.appBarTitle,
|
||||
description: widget.description,
|
||||
infoList: widget.infoList,
|
||||
)
|
||||
: widget.baseViewModel != null
|
||||
? NetworkBaseView(
|
||||
child: buildBodyWidget(),
|
||||
baseViewModel: widget.baseViewModel,
|
||||
)
|
||||
: buildBodyWidget(),
|
||||
bottomSheet: widget.bottomSheet,
|
||||
//floatingActionButton: floatingActionButton ?? floatingActionButton,
|
||||
// bottomNavigationBar:
|
||||
// this.isBottomBar == true ? BottomBarSearch() : SizedBox()
|
||||
// floatingActionButton: FloatingSearchButton(),
|
||||
);
|
||||
}
|
||||
|
||||
buildAppLoaderWidget(bool isLoading) {
|
||||
return isLoading ? AppLoaderWidget() : Container();
|
||||
}
|
||||
|
||||
buildBodyWidget() {
|
||||
// return body; //Stack(children: <Widget>[body, buildAppLoaderWidget(isLoading)]);
|
||||
return Stack(children: <Widget>[
|
||||
widget.body, /*FloatingSearchButton()*/
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
class AppBarWidget extends StatelessWidget with PreferredSizeWidget {
|
||||
final AuthenticatedUserObject authenticatedUserObject =
|
||||
locator<AuthenticatedUserObject>();
|
||||
|
||||
final String appBarTitle;
|
||||
final List<Widget> appBarIcons;
|
||||
final bool isShowAppBar;
|
||||
final bool isPharmacy;
|
||||
final bool isShowDecPage;
|
||||
final String image;
|
||||
|
||||
AppBarWidget(this.appBarTitle, this.appBarIcons, this.isShowAppBar,
|
||||
{this.isPharmacy = true, this.isShowDecPage = true, this.image});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return buildAppBar(context);
|
||||
}
|
||||
|
||||
Widget buildAppBar(BuildContext context) {
|
||||
return isShowAppBar
|
||||
? AppBar(
|
||||
elevation: 0,
|
||||
backgroundColor:Colors.white,
|
||||
// isPharmacy ? Colors.green : Theme.of(context).appBarTheme.color,
|
||||
textTheme: TextTheme(
|
||||
headline6:
|
||||
TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
|
||||
),
|
||||
title: Texts(
|
||||
authenticatedUserObject.isLogin || !isShowDecPage
|
||||
? appBarTitle.toUpperCase()
|
||||
: TranslationBase.of(context).serviceInformationTitle,
|
||||
color: Colors.white,
|
||||
bold: true,
|
||||
),
|
||||
leading: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return GestureDetector(
|
||||
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap:()=> Navigator.pop(context),
|
||||
child: Icon(Icons.arrow_back_ios, color: Colors.grey),
|
||||
);
|
||||
},
|
||||
),
|
||||
centerTitle: true,
|
||||
actions: <Widget>[
|
||||
isPharmacy
|
||||
? IconButton(
|
||||
icon: Icon(Icons.shopping_cart),
|
||||
color: Colors.grey,
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => CartOrderPage()),
|
||||
);
|
||||
// Navigator.of(context)
|
||||
// .popUntil(ModalRoute.withName('/'));
|
||||
})
|
||||
: Container(),
|
||||
image != null
|
||||
? InkWell(
|
||||
onTap: () => Navigator.push(
|
||||
context,
|
||||
FadePage(
|
||||
page: InsuranceUpdate(),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Image.asset(
|
||||
image,
|
||||
height: SizeConfig.heightMultiplier * 5,
|
||||
width: SizeConfig.heightMultiplier * 5,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
)
|
||||
: IconButton(
|
||||
icon: Icon(FontAwesomeIcons.ellipsisV),
|
||||
color: Colors.grey,
|
||||
onPressed: () {
|
||||
settingModalBottomSheet(context);
|
||||
},
|
||||
),
|
||||
if (appBarIcons != null) ...appBarIcons
|
||||
],
|
||||
)
|
||||
: Container(
|
||||
height: 0,
|
||||
width: 0,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Size get preferredSize => Size(double.maxFinite, 60);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue