├── ios ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ ├── flutter_export_environment.sh │ └── AppFrameworkInfo.plist ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── Runner.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ └── project.pbxproj ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── WorkspaceSettings.xcsettings │ │ └── IDEWorkspaceChecks.plist └── .gitignore ├── android ├── gradle.properties ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── drawable │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable-v21 │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── values │ │ │ │ │ └── styles.xml │ │ │ │ └── values-night │ │ │ │ │ └── styles.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── mtfa │ │ │ │ │ └── odooclient │ │ │ │ │ └── MainActivity.kt │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ └── build.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle └── build.gradle ├── assets ├── fonts │ ├── Roboto-Black.ttf │ ├── Roboto-Bold.ttf │ ├── Roboto-Light.ttf │ ├── Roboto-Thin.ttf │ ├── Roboto-Italic.ttf │ ├── Roboto-Medium.ttf │ ├── Roboto-Regular.ttf │ ├── Roboto-BoldItalic.ttf │ ├── Roboto-ThinItalic.ttf │ ├── Roboto-BlackItalic.ttf │ ├── Roboto-LightItalic.ttf │ └── Roboto-MediumItalic.ttf └── images │ ├── back_arrow.png │ ├── 2.0x │ └── back_arrow.png │ └── 3.0x │ └── back_arrow.png ├── lib ├── common │ ├── config │ │ ├── app_images.dart │ │ ├── prefs │ │ │ ├── pref_keys.dart │ │ │ └── pref_utils.dart │ │ ├── localization │ │ │ ├── translations.dart │ │ │ ├── localize.dart │ │ │ └── en.dart │ │ ├── dependencies.dart │ │ ├── config.dart │ │ ├── app_colors.dart │ │ ├── extentions.dart │ │ └── app_fonts.dart │ ├── widgets │ │ ├── log.dart │ │ ├── empty_view.dart │ │ ├── custom_button.dart │ │ ├── custom_drawer.dart │ │ ├── main_container.dart │ │ ├── date_picker.dart │ │ └── text_input.dart │ ├── api_factory │ │ ├── models │ │ │ ├── base_list.dart │ │ │ └── version_info_response.dart │ │ ├── modules │ │ │ ├── home_api_module.dart │ │ │ └── authentication_module.dart │ │ ├── odoo_response.dart │ │ ├── api_end_points.dart │ │ ├── base_response.dart │ │ ├── odoo_version.dart │ │ ├── dio_factory.dart │ │ └── api.dart │ ├── app.dart │ └── utils │ │ └── utils.dart ├── src │ ├── authentication │ │ ├── controllers │ │ │ └── signin_controller.dart │ │ ├── models │ │ │ └── user_model.dart │ │ └── views │ │ │ └── signin.dart │ └── home │ │ ├── controller │ │ └── home_controller.dart │ │ ├── model │ │ └── res_partner_model.dart │ │ └── view │ │ └── home.dart └── main.dart ├── .metadata ├── .gitignore ├── test └── widget_test.dart ├── README.md ├── pubspec.yaml ├── .flutter-plugins-dependencies └── pubspec.lock /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /assets/fonts/Roboto-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/assets/fonts/Roboto-Black.ttf -------------------------------------------------------------------------------- /assets/fonts/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/assets/fonts/Roboto-Bold.ttf -------------------------------------------------------------------------------- /assets/fonts/Roboto-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/assets/fonts/Roboto-Light.ttf -------------------------------------------------------------------------------- /assets/fonts/Roboto-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/assets/fonts/Roboto-Thin.ttf -------------------------------------------------------------------------------- /assets/images/back_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/assets/images/back_arrow.png -------------------------------------------------------------------------------- /assets/fonts/Roboto-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/assets/fonts/Roboto-Italic.ttf -------------------------------------------------------------------------------- /assets/fonts/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/assets/fonts/Roboto-Medium.ttf -------------------------------------------------------------------------------- /assets/fonts/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/assets/fonts/Roboto-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/Roboto-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/assets/fonts/Roboto-BoldItalic.ttf -------------------------------------------------------------------------------- /assets/fonts/Roboto-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/assets/fonts/Roboto-ThinItalic.ttf -------------------------------------------------------------------------------- /assets/images/2.0x/back_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/assets/images/2.0x/back_arrow.png -------------------------------------------------------------------------------- /assets/images/3.0x/back_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/assets/images/3.0x/back_arrow.png -------------------------------------------------------------------------------- /assets/fonts/Roboto-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/assets/fonts/Roboto-BlackItalic.ttf -------------------------------------------------------------------------------- /assets/fonts/Roboto-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/assets/fonts/Roboto-LightItalic.ttf -------------------------------------------------------------------------------- /assets/fonts/Roboto-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/assets/fonts/Roboto-MediumItalic.ttf -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /lib/common/config/app_images.dart: -------------------------------------------------------------------------------- 1 | class AppImages { 2 | AppImages._(); 3 | 4 | static const String basePath = "assets/images"; 5 | 6 | static const String ic_back = "$basePath/ic_back.png"; 7 | } 8 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/mtfa/odooclient/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.mtfa.odooclient 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mustafal/Odoo-JsonRpc-with-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/common/config/prefs/pref_keys.dart: -------------------------------------------------------------------------------- 1 | class PrefKeys { 2 | PrefKeys._(); 3 | 4 | static const String user = "user"; 5 | static const String token = "token"; 6 | static const String isLoggedIn = "isLoggedIn"; 7 | } 8 | -------------------------------------------------------------------------------- /lib/common/widgets/log.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | 3 | class Log { 4 | Log(var value) { 5 | if (!kReleaseMode) 6 | print("===============> ${value.toString()} <====================="); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip 7 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/common/config/localization/translations.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | 3 | import 'en.dart'; 4 | 5 | class AppTranslations extends Translations { 6 | @override 7 | // TODO: implement keys 8 | Map> get keys => { 9 | 'en': EN.Lang(), 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/common/config/dependencies.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | import 'package:odoo_common_code_latest/src/authentication/controllers/signin_controller.dart'; 3 | 4 | class Dependencies { 5 | Dependencies._(); 6 | 7 | static void injectDependencies() { 8 | Get.put(SignInController()); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /lib/common/config/localization/localize.dart: -------------------------------------------------------------------------------- 1 | class Localize { 2 | Localize._(); 3 | 4 | static String cancel = "cancel"; 5 | static String done = "done"; 6 | static String home = "home"; 7 | static String password = "password"; 8 | static String signin = "signin"; 9 | static String email = "email"; 10 | } 11 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: b22742018b3edf16c6cadd7b76d9db5e7f9064b5 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/common/config/localization/en.dart: -------------------------------------------------------------------------------- 1 | import 'package:odoo_common_code_latest/common/config/localization/localize.dart'; 2 | 3 | class EN { 4 | static Map Lang() { 5 | return { 6 | Localize.cancel: "Cancel", 7 | Localize.done: "Done", 8 | Localize.home: "Home", 9 | Localize.password: "Password", 10 | Localize.signin: "Sign In", 11 | Localize.email: "Email", 12 | }; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/src/authentication/controllers/signin_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | import 'package:odoo_common_code_latest/common/config/prefs/pref_utils.dart'; 3 | import 'package:odoo_common_code_latest/src/authentication/models/user_model.dart'; 4 | 5 | var currentUser = UserModel().obs; 6 | 7 | class SignInController extends GetxController { 8 | @override 9 | void onInit() async { 10 | super.onInit(); 11 | currentUser.value = await PrefUtils.getUser(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /lib/src/home/controller/home_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:get/get.dart'; 2 | import 'package:odoo_common_code_latest/common/api_factory/modules/home_api_module.dart'; 3 | import 'package:odoo_common_code_latest/src/home/model/res_partner_model.dart'; 4 | 5 | class HomeController extends GetxController { 6 | var listOfPartners = [].obs; 7 | 8 | getPartners() { 9 | resPartnerApi( 10 | onResponse: (response) { 11 | listOfPartners.assignAll(response.records!); 12 | }, 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Flutter/flutter_export_environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is a generated file; do not edit or check into version control. 3 | export "FLUTTER_ROOT=C:\src\flutter" 4 | export "FLUTTER_APPLICATION_PATH=F:\Work\Flutter Work\Odoo-JsonRpc-with-Flutter" 5 | export "COCOAPODS_PARALLEL_CODE_SIGN=true" 6 | export "FLUTTER_TARGET=lib\main.dart" 7 | export "FLUTTER_BUILD_DIR=build" 8 | export "FLUTTER_BUILD_NAME=1.0.0" 9 | export "FLUTTER_BUILD_NUMBER=1" 10 | export "DART_OBFUSCATION=false" 11 | export "TRACK_WIDGET_CREATION=true" 12 | export "TREE_SHAKE_ICONS=false" 13 | export "PACKAGE_CONFIG=.dart_tool/package_config.json" 14 | -------------------------------------------------------------------------------- /lib/common/api_factory/models/base_list.dart: -------------------------------------------------------------------------------- 1 | class BaseListModel { 2 | int? id; 3 | String? name; 4 | bool isSelected = false; 5 | 6 | BaseListModel({this.id, this.name, this.isSelected = false}); 7 | 8 | factory BaseListModel.fromJson(Map json) { 9 | return BaseListModel( 10 | id: json['id'], 11 | name: json['name'], 12 | isSelected: false, 13 | ); 14 | } 15 | 16 | Map toJson() { 17 | final Map data = new Map(); 18 | data['id'] = this.id; 19 | data['name'] = this.name; 20 | return data; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/common/widgets/empty_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:odoo_common_code_latest/common/config/app_colors.dart'; 3 | import 'package:odoo_common_code_latest/common/config/app_fonts.dart'; 4 | 5 | class EmptyView extends StatelessWidget { 6 | String errorMsg; 7 | 8 | EmptyView({required this.errorMsg}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container( 13 | padding: const EdgeInsets.only(right: 16.0), 14 | alignment: Alignment.center, 15 | child: Text( 16 | errorMsg, 17 | style: AppFont.Caption1_Body(color: AppColors.grey), 18 | ), 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:odoo_common_code_latest/common/api_factory/dio_factory.dart'; 3 | import 'package:odoo_common_code_latest/common/app.dart'; 4 | import 'package:odoo_common_code_latest/common/config/dependencies.dart'; 5 | import 'package:odoo_common_code_latest/common/config/prefs/pref_utils.dart'; 6 | 7 | void main() async { 8 | WidgetsFlutterBinding.ensureInitialized(); 9 | 10 | // Controller dependencies which we use throughout the app 11 | Dependencies.injectDependencies(); 12 | 13 | DioFactory.initialiseHeaders(await PrefUtils.getToken()); 14 | 15 | bool isLoggedIn = await PrefUtils.getIsLoggedIn(); 16 | runApp(App(isLoggedIn)); 17 | } 18 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.8.20' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.3.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | tasks.register("clean", Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/ephemeral/ 22 | Flutter/app.flx 23 | Flutter/app.zip 24 | Flutter/flutter_assets/ 25 | Flutter/flutter_export_environment.sh 26 | ServiceDefinitions.json 27 | Runner/GeneratedPluginRegistrant.* 28 | 29 | # Exceptions to above rules. 30 | !default.mode1v3 31 | !default.mode2v3 32 | !default.pbxuser 33 | !default.perspectivev3 34 | -------------------------------------------------------------------------------- /lib/common/widgets/custom_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class CustomButton extends StatelessWidget { 4 | var onPress; 5 | Widget child; 6 | var color; 7 | 8 | CustomButton({this.onPress, required this.child, this.color}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return MaterialButton( 13 | height: 56.0, 14 | onPressed: onPress, 15 | elevation: 0.0, 16 | shape: RoundedRectangleBorder( 17 | borderRadius: BorderRadius.circular(8.0), 18 | ), 19 | textColor: Colors.white, 20 | child: child, 21 | color: color ?? Theme.of(context).buttonTheme.colorScheme?.onSecondary, 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/common/api_factory/modules/home_api_module.dart: -------------------------------------------------------------------------------- 1 | import 'package:odoo_common_code_latest/common/api_factory/api.dart'; 2 | import 'package:odoo_common_code_latest/common/api_factory/dio_factory.dart'; 3 | import 'package:odoo_common_code_latest/common/utils/utils.dart'; 4 | import 'package:odoo_common_code_latest/src/home/model/res_partner_model.dart'; 5 | 6 | resPartnerApi({required OnResponse onResponse}) { 7 | Api.searchRead( 8 | model: "res.partner", 9 | domain: [], 10 | fields: ["name", "email", "image_512"], 11 | onResponse: (response) { 12 | onResponse(ResPartnerModel.fromJson(response)); 13 | }, 14 | onError: (error, data) { 15 | handleApiError(error); 16 | }, 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /lib/common/api_factory/odoo_response.dart: -------------------------------------------------------------------------------- 1 | class OdooResponse { 2 | var _result, _statusCode; 3 | 4 | OdooResponse(Map result, int statusCode) { 5 | _result = result; 6 | _statusCode = statusCode; 7 | } 8 | 9 | bool hasError() { 10 | return _result['error'] != null; 11 | } 12 | 13 | Map getError() { 14 | return _result['error']; 15 | } 16 | 17 | String getErrorMessage() { 18 | if (hasError()) { 19 | return _result['error']['data']['message']; 20 | } 21 | return ""; 22 | } 23 | 24 | int getStatusCode() { 25 | return _statusCode; 26 | } 27 | 28 | dynamic getResult() { 29 | return _result['result']; 30 | } 31 | 32 | dynamic getRecords() { 33 | return getResult()['records']; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/common/api_factory/api_end_points.dart: -------------------------------------------------------------------------------- 1 | class ApiEndPoints { 2 | ApiEndPoints._(); 3 | 4 | static const String getSessionInfo = "web/session/get_session_info"; 5 | static const String destroy = "web/session/destroy"; 6 | static const String authenticate = "web/session/authenticate"; 7 | static const String searchRead = "web/dataset/search_read"; 8 | static const String callKw = "web/dataset/call_kw/"; 9 | static const String getVersionInfo = "web/webclient/version_info"; 10 | static const String getDb9 = "jsonrpc"; 11 | static const String getDb10 = "web/database/list"; 12 | static const String getDb = "web/database/get_list"; 13 | 14 | static String getCallKWEndPoint(String model, String method) { 15 | return '$callKw/$model/$method'; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /lib/common/api_factory/base_response.dart: -------------------------------------------------------------------------------- 1 | class BaseResponse { 2 | dynamic result; 3 | List? error; 4 | int? success; 5 | 6 | BaseResponse({this.result, this.error, this.success}); 7 | 8 | factory BaseResponse.fromJson(Map json) { 9 | return BaseResponse( 10 | result: json['result'] != null ? json['result'] : null, 11 | error: json['error'] != null 12 | ? (json['error'] as List).map((i) => i).toList() 13 | : null, 14 | success: json['success'], 15 | ); 16 | } 17 | 18 | Map toJson() { 19 | final Map result = new Map(); 20 | result['success'] = this.success; 21 | if (this.result != null) { 22 | result['result'] = this.result.toJson(); 23 | } 24 | 25 | if (this.error != null) { 26 | result['error'] = this.error!.map((v) => v).toList(); 27 | } 28 | return result; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /lib/common/widgets/custom_drawer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class CustomDrawer extends StatelessWidget { 4 | CustomDrawer(); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | return Drawer( 9 | child: ListView( 10 | children: [ 11 | UserAccountsDrawerHeader( 12 | currentAccountPicture: CircleAvatar( 13 | radius: 30.0, 14 | backgroundColor: Colors.transparent, 15 | backgroundImage: NetworkImage( 16 | "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/John_Doe%2C_born_John_Nommensen_Duchac.jpg/1200px-John_Doe%2C_born_John_Nommensen_Duchac.jpg", 17 | ), 18 | ), 19 | accountName: Text("Mustafa Lokhandwala"), 20 | accountEmail: Text("mustafa.mscit15@gmail.com"), 21 | ), 22 | ListTile( 23 | leading: Icon(Icons.account_circle), 24 | title: Text("Edit Profile"), 25 | onTap: () {}, 26 | ), 27 | ], 28 | ), 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | import 'package:odoo_common_code_latest/common/app.dart'; 11 | 12 | void main() { 13 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 14 | // Build our app and trigger a frame. 15 | await tester.pumpWidget(App(false)); 16 | 17 | // Verify that our counter starts at 0. 18 | expect(find.text('0'), findsOneWidget); 19 | expect(find.text('1'), findsNothing); 20 | 21 | // Tap the '+' icon and trigger a frame. 22 | await tester.tap(find.byIcon(Icons.add)); 23 | await tester.pump(); 24 | 25 | // Verify that our counter has incremented. 26 | expect(find.text('0'), findsNothing); 27 | expect(find.text('1'), findsOneWidget); 28 | }); 29 | } 30 | -------------------------------------------------------------------------------- /lib/common/config/config.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | class Config { 4 | Config._(); 5 | 6 | ///Odoo URLs 7 | static const String OdooDevURL = "https://40767647-16-0-all.runbot153.odoo.com/"; 8 | static const String OdooProdURL = "https://40767647-16-0-all.runbot153.odoo.com/"; 9 | static const String OdooUATURL = "https://40767647-16-0-all.runbot153.odoo.com/"; 10 | 11 | /// SelfSignedCert: 12 | static const selfSignedCert = false; 13 | 14 | /// API Config 15 | static const timeout = 60000; 16 | static const logNetworkRequest = true; 17 | static const logNetworkRequestHeader = true; 18 | static const logNetworkRequestBody = true; 19 | static const logNetworkResponseHeader = false; 20 | static const logNetworkResponseBody = true; 21 | static const logNetworkError = true; 22 | 23 | /// Localization Config 24 | static const supportedLocales = [Locale('en', ''), Locale('pt', '')]; 25 | 26 | /// Common Const 27 | static const actionLocale = 'locale'; 28 | static const int SIGNUP = 0; 29 | static const int SIGNIN = 1; 30 | static const String CURRENCY_SYMBOL = "€"; 31 | static String FCM_TOKEN = ""; 32 | static String DB = ""; 33 | } 34 | -------------------------------------------------------------------------------- /lib/src/home/model/res_partner_model.dart: -------------------------------------------------------------------------------- 1 | class ResPartnerModel { 2 | List? records; 3 | 4 | ResPartnerModel({this.records}); 5 | 6 | ResPartnerModel.fromJson(dynamic json) { 7 | if (json["records"] != null) { 8 | records = []; 9 | json["records"].forEach((v) { 10 | records?.add(Records.fromJson(v)); 11 | }); 12 | } 13 | } 14 | 15 | Map toJson() { 16 | var map = {}; 17 | if (records != null) { 18 | map["records"] = records?.map((v) => v.toJson()).toList(); 19 | } 20 | return map; 21 | } 22 | } 23 | 24 | class Records { 25 | int? id; 26 | String? name; 27 | String? email; 28 | String? image512; 29 | 30 | Records({this.id, this.name, this.email, this.image512}); 31 | 32 | Records.fromJson(dynamic json) { 33 | id = json["id"]; 34 | name = json["name"]; 35 | email = json["email"] is! bool ? json["email"] : ""; 36 | image512 = json["image_512"] is! bool ? json["image_512"] : ""; 37 | } 38 | 39 | Map toJson() { 40 | var map = {}; 41 | map["id"] = id; 42 | map["name"] = name; 43 | map["email"] = email; 44 | map["image_512"] = image512; 45 | return map; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/common/api_factory/models/version_info_response.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | VersionInfoResponse welcomeFromJson(String str) => 4 | VersionInfoResponse.fromJson(json.decode(str)); 5 | 6 | String welcomeToJson(VersionInfoResponse data) => json.encode(data.toJson()); 7 | 8 | class VersionInfoResponse { 9 | VersionInfoResponse({ 10 | this.serverVersion, 11 | this.serverVersionInfo, 12 | this.serverSerie, 13 | this.protocolVersion, 14 | }); 15 | 16 | String? serverVersion; 17 | List? serverVersionInfo; 18 | String? serverSerie; 19 | int? protocolVersion; 20 | 21 | factory VersionInfoResponse.fromJson(Map json) => 22 | VersionInfoResponse( 23 | serverVersion: json["server_version"] ?? '', 24 | serverVersionInfo: 25 | List.from(json["server_version_info"].map((x) => x)), 26 | serverSerie: json["server_serie"] ?? '', 27 | protocolVersion: json["protocol_version"] ?? 0, 28 | ); 29 | 30 | Map toJson() => { 31 | "server_version": serverVersion, 32 | "server_version_info": 33 | List.from(serverVersionInfo!.map((x) => x)), 34 | "server_serie": serverSerie, 35 | "protocol_version": protocolVersion, 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Odoo Mobile Framework With Flutter 2 | Odoo Mobile framework with flutter 3 | 4 | This Project Supports **All Odoo Community and Enterprise Editions**. It may not work properly against older versions of Odoo. 5 | 6 | # Supported Platforms 7 | -> Android 8 | -> iOS 9 | 10 | # MIT License 11 | 12 | Copyright (c) 2019 Mustafa Lokhandwala 13 | 14 | Permission is hereby granted, free of charge, to any person obtaining a copy 15 | of this software and associated documentation files (the "Software"), to deal 16 | in the Software without restriction, including without limitation the rights 17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | copies of the Software, and to permit persons to whom the Software is 19 | furnished to do so, subject to the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included in all 22 | copies or substantial portions of the Software. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 | SOFTWARE. -------------------------------------------------------------------------------- /lib/common/widgets/main_container.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:odoo_common_code_latest/common/config/app_fonts.dart'; 3 | 4 | class MainContainer extends StatelessWidget { 5 | String? appBarTitle; 6 | Widget child; 7 | List? actions = []; 8 | bool isAppBar = true; 9 | Widget? leading; 10 | Color? backgroundColor; 11 | Widget? floatingActionButton; 12 | double? padding, elevation; 13 | Widget? bottomNavigationBar; 14 | 15 | MainContainer( 16 | {required this.child, 17 | this.backgroundColor, 18 | this.appBarTitle, 19 | this.isAppBar = true, 20 | this.actions, 21 | this.floatingActionButton, 22 | this.padding, 23 | this.elevation, 24 | this.leading, 25 | this.bottomNavigationBar}); 26 | 27 | @override 28 | Widget build(BuildContext context) { 29 | return Scaffold( 30 | floatingActionButton: floatingActionButton ?? null, 31 | appBar: isAppBar == true 32 | ? AppBar( 33 | iconTheme: IconThemeData(color: Colors.white), 34 | leading: leading ?? null, 35 | elevation: elevation ?? 0.0, 36 | centerTitle: true, 37 | actions: actions, 38 | title: Text(appBarTitle ?? '', 39 | style: AppFont.Title_H6_Medium(color: Colors.white)), 40 | ) 41 | : null, 42 | body: SafeArea( 43 | child: SingleChildScrollView( 44 | padding: EdgeInsets.all(padding ?? 0.0), 45 | child: child, 46 | ), 47 | ), 48 | bottomNavigationBar: bottomNavigationBar ?? null, 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | odoo_common_code_latest 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /lib/common/config/prefs/pref_utils.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:odoo_common_code_latest/common/config/prefs/pref_keys.dart'; 4 | import 'package:odoo_common_code_latest/src/authentication/models/user_model.dart'; 5 | import 'package:shared_preferences/shared_preferences.dart'; 6 | 7 | class PrefUtils { 8 | PrefUtils(); 9 | 10 | static setToken(String token) async { 11 | SharedPreferences preferences = await SharedPreferences.getInstance(); 12 | await preferences.setString(PrefKeys.token, token); 13 | } 14 | 15 | static Future getToken() async { 16 | SharedPreferences preferences = await SharedPreferences.getInstance(); 17 | return preferences.getString(PrefKeys.token) ?? ""; 18 | } 19 | 20 | static setIsLoggedIn(bool isLoggedIn) async { 21 | SharedPreferences preferences = await SharedPreferences.getInstance(); 22 | await preferences.setBool(PrefKeys.isLoggedIn, isLoggedIn); 23 | } 24 | 25 | static Future getIsLoggedIn() async { 26 | SharedPreferences preferences = await SharedPreferences.getInstance(); 27 | return preferences.getBool(PrefKeys.isLoggedIn) ?? false; 28 | } 29 | 30 | static setUser(String userData) async { 31 | SharedPreferences preferences = await SharedPreferences.getInstance(); 32 | return preferences.setString(PrefKeys.user, userData); 33 | } 34 | 35 | static Future getUser() async { 36 | SharedPreferences preferences = await SharedPreferences.getInstance(); 37 | Map user = 38 | jsonDecode(preferences.getString(PrefKeys.user) ?? "{}"); 39 | return UserModel.fromJson(user); 40 | } 41 | 42 | static clearPrefs() async { 43 | SharedPreferences preferences = await SharedPreferences.getInstance(); 44 | await preferences.clear(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/common/api_factory/odoo_version.dart: -------------------------------------------------------------------------------- 1 | import 'package:odoo_common_code_latest/common/api_factory/odoo_response.dart'; 2 | 3 | class OdooVersion { 4 | var _version, _serverSerie, _protocolVersion; 5 | var _major, _minor, _micro, _releaseLevel, _serial; 6 | bool _isEnterprise = false; 7 | 8 | String getVersionInfo() { 9 | return _version; 10 | } 11 | 12 | int getServerSerie() { 13 | return _serverSerie; 14 | } 15 | 16 | int getProtocolVersion() { 17 | return _protocolVersion; 18 | } 19 | 20 | dynamic getMajorVersion() { 21 | return _major; 22 | } 23 | 24 | int getMinorVersion() { 25 | return _minor; 26 | } 27 | 28 | int getMicroVersion() { 29 | return _micro; 30 | } 31 | 32 | String getReleaseLevel() { 33 | return _releaseLevel; 34 | } 35 | 36 | String getSerial() { 37 | return _serial; 38 | } 39 | 40 | bool isEnterprise() { 41 | return _isEnterprise; 42 | } 43 | 44 | OdooVersion parse(OdooResponse response) { 45 | Map result = response.getResult(); 46 | _version = result['server_version']; 47 | _serverSerie = result['server_serie']; 48 | _protocolVersion = result['protocol_version']; 49 | List versionInfo = result['server_version_info']; 50 | if (versionInfo.length == 6) { 51 | _isEnterprise = versionInfo.last == "e"; 52 | } 53 | _major = versionInfo[0]; 54 | _minor = versionInfo[1]; 55 | _micro = versionInfo[2]; 56 | _releaseLevel = versionInfo[3]; 57 | _serial = versionInfo[4]; 58 | return this; 59 | } 60 | 61 | @override 62 | String toString() { 63 | if (_version != null) { 64 | return "$_version (${_isEnterprise ? 'Enterprise' : 'Community'})"; 65 | } 66 | return "Not Connected: Please call connect() or getVersionInfo() with callback."; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 33 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | defaultConfig { 36 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 37 | applicationId "com.mtfa.odooclient" 38 | minSdkVersion 21 39 | targetSdkVersion 30 40 | versionCode flutterVersionCode.toInteger() 41 | versionName flutterVersionName 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 59 | } 60 | -------------------------------------------------------------------------------- /lib/common/api_factory/modules/authentication_module.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:get/get.dart'; 4 | import 'package:odoo_common_code_latest/common/api_factory/api.dart'; 5 | import 'package:odoo_common_code_latest/common/config/config.dart'; 6 | import 'package:odoo_common_code_latest/common/config/prefs/pref_utils.dart'; 7 | import 'package:odoo_common_code_latest/common/utils/utils.dart'; 8 | import 'package:odoo_common_code_latest/common/widgets/log.dart'; 9 | import 'package:odoo_common_code_latest/src/authentication/controllers/signin_controller.dart'; 10 | import 'package:odoo_common_code_latest/src/authentication/models/user_model.dart'; 11 | import 'package:odoo_common_code_latest/src/authentication/views/signin.dart'; 12 | import 'package:odoo_common_code_latest/src/home/view/home.dart'; 13 | 14 | getVersionInfoAPI() { 15 | Api.getVersionInfo( 16 | onResponse: (response) { 17 | Api.getDatabases( 18 | serverVersionNumber: response.serverVersionInfo![0], 19 | onResponse: (response) { 20 | Log(response); 21 | Config.DB = response[0]; 22 | }, 23 | onError: (error, data) { 24 | handleApiError(error); 25 | }, 26 | ); 27 | }, 28 | onError: (error, data) { 29 | handleApiError(error); 30 | }, 31 | ); 32 | } 33 | 34 | authenticationAPI(String email, String pass) { 35 | Api.authenticate( 36 | username: email, 37 | password: pass, 38 | database: Config.DB, 39 | onResponse: (UserModel response) { 40 | currentUser.value = response; 41 | PrefUtils.setIsLoggedIn(true); 42 | PrefUtils.setUser(jsonEncode(response)); 43 | Get.offAll(() => Home()); 44 | }, 45 | onError: (error, data) { 46 | handleApiError(error); 47 | }, 48 | ); 49 | } 50 | 51 | logoutApi() { 52 | Api.destroy( 53 | onResponse: (response) { 54 | PrefUtils.clearPrefs(); 55 | Get.offAll(() => SignIn()); 56 | }, 57 | onError: (error, data) { 58 | handleApiError(error); 59 | }, 60 | ); 61 | } 62 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 7 | 14 | 18 | 21 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 36 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /lib/common/app.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:flutter/foundation.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_localizations/flutter_localizations.dart'; 6 | import 'package:get/get.dart'; 7 | import 'package:odoo_common_code_latest/common/api_factory/dio_factory.dart'; 8 | import 'package:odoo_common_code_latest/common/config/app_colors.dart'; 9 | import 'package:odoo_common_code_latest/common/config/app_fonts.dart'; 10 | import 'package:odoo_common_code_latest/common/config/config.dart'; 11 | import 'package:odoo_common_code_latest/common/config/localization/translations.dart'; 12 | import 'package:odoo_common_code_latest/src/authentication/views/signin.dart'; 13 | import 'package:odoo_common_code_latest/src/home/view/home.dart'; 14 | 15 | class App extends StatefulWidget { 16 | final bool isLoggedIn; 17 | 18 | App(this.isLoggedIn); 19 | 20 | @override 21 | State createState() { 22 | return _AppState(); 23 | } 24 | } 25 | 26 | class _AppState extends State { 27 | var _initStateFlag = false; 28 | 29 | @override 30 | void initState() { 31 | super.initState(); 32 | if (!kReleaseMode) { 33 | log('initState', name: '_AppState::initState'); 34 | } 35 | _initStateFlag = true; 36 | } 37 | 38 | @override 39 | void didChangeDependencies() async { 40 | super.didChangeDependencies(); 41 | if (_initStateFlag) { 42 | _initStateFlag = false; 43 | await DioFactory.computeDeviceInfo(); 44 | } 45 | } 46 | 47 | @override 48 | Widget build(BuildContext context) { 49 | return GetMaterialApp( 50 | translations: AppTranslations(), 51 | locale: Get.deviceLocale, 52 | fallbackLocale: Locale('en', 'US'), 53 | theme: ThemeData( 54 | brightness: Brightness.light, 55 | primarySwatch: AppColors.orangeThemeColor, 56 | fontFamily: AppFont.Roboto_Regular, 57 | ), 58 | debugShowCheckedModeBanner: false, 59 | title: 'Odoo Inventory', 60 | localizationsDelegates: [ 61 | GlobalMaterialLocalizations.delegate, 62 | GlobalWidgetsLocalizations.delegate, 63 | ], 64 | supportedLocales: Config.supportedLocales, 65 | home: widget.isLoggedIn ? Home() : SignIn(), 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: odoo_common_code_latest 2 | description: A new Flutter project. 3 | 4 | publish_to: 'none' 5 | 6 | version: 1.0.0+1 7 | 8 | environment: 9 | sdk: ">=2.12.0 <3.0.0" 10 | 11 | dependencies: 12 | flutter_localizations: 13 | sdk: flutter 14 | flutter: 15 | sdk: flutter 16 | 17 | cupertino_icons: ^1.0.5 18 | intl: ^0.18.0 19 | device_info_plus: ^9.0.1 20 | dio: ^5.1.2 21 | shared_preferences: ^2.1.1 22 | get: ^4.6.5 23 | action_broadcast: ^3.0.1 24 | country_code_picker: ^3.0.0 25 | path_provider: ^2.0.15 26 | cached_network_image: ^3.2.3 27 | 28 | 29 | dev_dependencies: 30 | flutter_test: 31 | sdk: flutter 32 | 33 | flutter: 34 | fonts: 35 | - family: RobotoBlack 36 | fonts: 37 | - asset: assets/fonts/Roboto-Black.ttf 38 | - family: RobotoBlackItalic 39 | fonts: 40 | - asset: assets/fonts/Roboto-BlackItalic.ttf 41 | - family: RobotoBold 42 | fonts: 43 | - asset: assets/fonts/Roboto-Bold.ttf 44 | - family: RobotoBoldItalic 45 | fonts: 46 | - asset: assets/fonts/Roboto-BoldItalic.ttf 47 | - family: RobotoItalic 48 | fonts: 49 | - asset: assets/fonts/Roboto-Italic.ttf 50 | - family: RobotoLight 51 | fonts: 52 | - asset: assets/fonts/Roboto-Light.ttf 53 | - family: RobotoLightItalic 54 | fonts: 55 | - asset: assets/fonts/Roboto-LightItalic.ttf 56 | - family: RobotoMedium 57 | fonts: 58 | - asset: assets/fonts/Roboto-Medium.ttf 59 | - family: RobotoMediumItalic 60 | fonts: 61 | - asset: assets/fonts/Roboto-MediumItalic.ttf 62 | - family: RobotoRegular 63 | fonts: 64 | - asset: assets/fonts/Roboto-Regular.ttf 65 | - family: RobotoThin 66 | fonts: 67 | - asset: assets/fonts/Roboto-Thin.ttf 68 | - family: RobotoThinItalic 69 | fonts: 70 | - asset: assets/fonts/Roboto-ThinItalic.ttf 71 | uses-material-design: true 72 | assets: 73 | - assets/images/ 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /lib/src/home/view/home.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:get/get.dart'; 5 | import 'package:odoo_common_code_latest/common/config/app_colors.dart'; 6 | import 'package:odoo_common_code_latest/common/utils/utils.dart'; 7 | import 'package:odoo_common_code_latest/common/widgets/main_container.dart'; 8 | import 'package:odoo_common_code_latest/src/home/controller/home_controller.dart'; 9 | 10 | class Home extends StatefulWidget { 11 | @override 12 | _HomeState createState() => _HomeState(); 13 | } 14 | 15 | class _HomeState extends State { 16 | final _homeController = Get.put(HomeController()); 17 | 18 | @override 19 | void initState() { 20 | super.initState(); 21 | _homeController.getPartners(); 22 | } 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | return MainContainer( 27 | isAppBar: true, 28 | appBarTitle: "Home", 29 | padding: 20.0, 30 | actions: [ 31 | IconButton( 32 | onPressed: () { 33 | showLogoutDialog(); 34 | }, 35 | icon: Icon(Icons.exit_to_app), 36 | ) 37 | ], 38 | child: Obx( 39 | () { 40 | return ListView.builder( 41 | shrinkWrap: true, 42 | physics: ScrollPhysics(), 43 | itemCount: _homeController.listOfPartners.length, 44 | itemBuilder: (context, index) { 45 | return ListTile( 46 | leading: ClipRRect( 47 | borderRadius: BorderRadius.circular(8.0), 48 | child: _homeController 49 | .listOfPartners[index].image512!.isNotEmpty 50 | ? Image.memory( 51 | base64.decode( 52 | _homeController.listOfPartners[index].image512!), 53 | height: 40, 54 | width: 40, 55 | ) 56 | : Icon( 57 | Icons.person, 58 | color: AppColors.grey, 59 | size: 40, 60 | ), 61 | ), 62 | title: Text(_homeController.listOfPartners[index].name!), 63 | subtitle: Text(_homeController.listOfPartners[index].email!), 64 | ); 65 | }, 66 | ); 67 | }, 68 | ), 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lib/common/config/app_colors.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class AppColors { 4 | AppColors._(); 5 | 6 | static Color black = HexColor("#212121"); 7 | static const homeBlack = Color(0xFF323643); 8 | static const subTitle = Color(0xFF707070); 9 | static const hintColor = Color(0xFFbabbbf); 10 | static const blue = Color(0xFF3277D8); 11 | static Color grey = HexColor("#757575"); 12 | static Color lightGrey = HexColor("#9E9E9E"); 13 | static Color greenColor = HexColor("#1BC500"); 14 | static Color blueBgColor = HexColor("#2C5BDC"); 15 | static Color textFieldBackgroundColor = HexColor("#FAFAFA"); 16 | static Color backgroundColor = HexColor("#F5F5F5"); 17 | static Color blueDotColor = HexColor("#2081FF"); 18 | static Color greyDotColor = HexColor("#E0E0E0"); 19 | static Color blueButtonColor = HexColor("#2081FF"); 20 | static Color orange = HexColor("#F57C51"); 21 | static Color dropDownArrowColor = HexColor("#424242"); 22 | 23 | static Color homeProposalSentBg = HexColor("#FFF3DA"); 24 | static Color homeCandidateLikeBg = HexColor("#DDEEFF"); 25 | static Color blueTextColor = HexColor("#2C5BDC"); 26 | static Color borderColor = HexColor("#EEEEEE"); 27 | static Color borderColorSingleLine = HexColor("#E0E0E0"); 28 | 29 | static Color iconColor = HexColor("#2E3A59"); 30 | static Color progressBackColor = HexColor("#D5FCDA"); 31 | static Color longTermBackColor = HexColor("#FFF3DA"); 32 | static Color badgeColor = HexColor("#FF7C70"); 33 | 34 | static Color statusAccept = HexColor("#189A75"); 35 | static Color statusNotAccept = HexColor("#DB5251"); 36 | static Color statusAcceptBg = HexColor("#D4FCD9"); 37 | static Color statusNotAcceptBg = HexColor("#FFEEE2"); 38 | 39 | static MaterialColor orangeThemeColor = const MaterialColor( 40 | 0xFFF57C51, 41 | const { 42 | 50: const Color(0xFFF57C51), 43 | 100: const Color(0xFFF57C51), 44 | 200: const Color(0xFFF57C51), 45 | 300: const Color(0xFFF57C51), 46 | 400: const Color(0xFFF57C51), 47 | 500: const Color(0xFFF57C51), 48 | 600: const Color(0xFFF57C51), 49 | 700: const Color(0xFFF57C51), 50 | 800: const Color(0xFFF57C51), 51 | 900: const Color(0xFFF57C51), 52 | }, 53 | ); 54 | } 55 | 56 | class HexColor extends Color { 57 | static int _getColorFromHex(String hexColor) { 58 | hexColor = hexColor.toUpperCase().replaceAll("#", ""); 59 | if (hexColor.length == 6) { 60 | hexColor = "FF" + hexColor; 61 | } 62 | return int.parse(hexColor, radix: 16); 63 | } 64 | 65 | HexColor(final String hexColor) : super(_getColorFromHex(hexColor)); 66 | } 67 | -------------------------------------------------------------------------------- /lib/src/authentication/models/user_model.dart: -------------------------------------------------------------------------------- 1 | class UserModel { 2 | UserModel({ 3 | this.uid, 4 | this.isAdmin, 5 | this.db, 6 | this.serverVersion, 7 | this.name, 8 | this.username, 9 | this.partnerDisplayName, 10 | this.companyId, 11 | this.partnerId, 12 | this.webBaseUrl, 13 | this.showEffect, 14 | this.displaySwitchCompanyMenu, 15 | this.maxTimeBetweenKeysInMs, 16 | this.outOfOfficeMessage, 17 | }); 18 | 19 | int? uid; 20 | bool? isAdmin; 21 | String? db; 22 | String? serverVersion; 23 | String? name; 24 | String? username; 25 | String? partnerDisplayName; 26 | int? companyId; 27 | int? partnerId; 28 | String? webBaseUrl; 29 | bool? showEffect; 30 | bool? displaySwitchCompanyMenu; 31 | int? maxTimeBetweenKeysInMs; 32 | bool? outOfOfficeMessage; 33 | 34 | factory UserModel.fromJson(Map json) => UserModel( 35 | uid: json["uid"], 36 | isAdmin: json["is_admin"], 37 | db: json["db"], 38 | serverVersion: json["server_version"], 39 | name: json["name"], 40 | username: json["username"], 41 | partnerDisplayName: json["partner_display_name"], 42 | companyId: json["company_id"], 43 | partnerId: json["partner_id"], 44 | webBaseUrl: json["web.base.url"], 45 | showEffect: json["show_effect"], 46 | displaySwitchCompanyMenu: json["display_switch_company_menu"], 47 | maxTimeBetweenKeysInMs: json["max_time_between_keys_in_ms"], 48 | outOfOfficeMessage: json["out_of_office_message"], 49 | ); 50 | 51 | Map toJson() => { 52 | "uid": uid, 53 | "is_admin": isAdmin, 54 | "db": db, 55 | "server_version": serverVersion, 56 | "name": name, 57 | "username": username, 58 | "partner_display_name": partnerDisplayName, 59 | "company_id": companyId, 60 | "partner_id": partnerId, 61 | "web.base.url": webBaseUrl, 62 | "show_effect": showEffect, 63 | "display_switch_company_menu": displaySwitchCompanyMenu, 64 | "max_time_between_keys_in_ms": maxTimeBetweenKeysInMs, 65 | "out_of_office_message": outOfOfficeMessage, 66 | }; 67 | } 68 | 69 | class Currency { 70 | Currency({ 71 | this.symbol, 72 | this.position, 73 | this.digits, 74 | }); 75 | 76 | String? symbol; 77 | String? position; 78 | List? digits; 79 | 80 | factory Currency.fromJson(Map json) => Currency( 81 | symbol: json["symbol"], 82 | position: json["position"], 83 | digits: List.from(json["digits"].map((x) => x)), 84 | ); 85 | 86 | Map toJson() => { 87 | "symbol": symbol, 88 | "position": position, 89 | "digits": List.from(digits!.map((x) => x)), 90 | }; 91 | } 92 | -------------------------------------------------------------------------------- /lib/common/api_factory/dio_factory.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer' show log; 2 | import 'dart:io'; 3 | 4 | import 'package:device_info_plus/device_info_plus.dart'; 5 | import 'package:dio/dio.dart'; 6 | import 'package:flutter/foundation.dart'; 7 | import 'package:odoo_common_code_latest/common/api_factory/api.dart'; 8 | import 'package:odoo_common_code_latest/common/config/config.dart'; 9 | 10 | typedef void OnError(String error, Map data); 11 | typedef void OnResponse(T response); 12 | 13 | class DioFactory { 14 | static final _singleton = DioFactory._instance(); 15 | 16 | static Dio? get dio => _singleton._dio; 17 | static var _deviceName = 'Generic Device'; 18 | static var _authorization = ''; 19 | 20 | static Future computeDeviceInfo() async { 21 | if (Platform.isAndroid || Platform.isIOS) { 22 | DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); 23 | if (Platform.isAndroid) { 24 | AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; 25 | _deviceName = '${androidInfo.brand} ${androidInfo.model}'; 26 | } else { 27 | IosDeviceInfo iosInfo = await deviceInfo.iosInfo; 28 | _deviceName = iosInfo.utsname.machine; 29 | } 30 | } else if (Platform.isFuchsia) { 31 | _deviceName = 'Generic Fuchsia Device'; 32 | } else if (Platform.isLinux) { 33 | _deviceName = 'Generic Linux Device'; 34 | } else if (Platform.isMacOS) { 35 | _deviceName = 'Generic Macintosh Device'; 36 | } else if (Platform.isWindows) { 37 | _deviceName = 'Generic Windows Device'; 38 | } 39 | 40 | return true; 41 | } 42 | 43 | static void initialiseHeaders(String token) { 44 | _authorization = token; 45 | _singleton._dio!.options.headers[HttpHeaders.cookieHeader] = _authorization; 46 | } 47 | 48 | static void initFCMToken(String token) { 49 | var _token = token; 50 | _singleton._dio!.options.headers["device_id"] = _token; 51 | } 52 | 53 | Dio? _dio; 54 | 55 | DioFactory._instance() { 56 | _dio = Dio( 57 | BaseOptions( 58 | baseUrl: ApiEnvironment.Dev.endpoint, 59 | headers: { 60 | HttpHeaders.userAgentHeader: _deviceName, 61 | HttpHeaders.authorizationHeader: _authorization, 62 | 'Keep-Alive': Config.timeout, 63 | }, 64 | connectTimeout: Duration(seconds: Config.timeout), 65 | receiveTimeout: Duration(seconds: Config.timeout), 66 | sendTimeout: Duration(seconds: Config.timeout), 67 | contentType: Headers.jsonContentType, 68 | ), 69 | ); 70 | if (!kReleaseMode) { 71 | _dio!.interceptors.add(LogInterceptor( 72 | request: Config.logNetworkRequest, 73 | requestHeader: Config.logNetworkRequestHeader, 74 | requestBody: Config.logNetworkRequestBody, 75 | responseHeader: Config.logNetworkResponseHeader, 76 | responseBody: Config.logNetworkResponseBody, 77 | error: Config.logNetworkError, 78 | logPrint: (Object object) { 79 | log(object.toString(), name: 'dio'); 80 | }, 81 | )); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /lib/src/authentication/views/signin.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | import 'package:odoo_common_code_latest/common/api_factory/modules/authentication_module.dart'; 4 | import 'package:odoo_common_code_latest/common/config/app_colors.dart'; 5 | import 'package:odoo_common_code_latest/common/config/localization/localize.dart'; 6 | import 'package:odoo_common_code_latest/common/utils/utils.dart'; 7 | import 'package:odoo_common_code_latest/common/widgets/custom_button.dart'; 8 | import 'package:odoo_common_code_latest/common/widgets/main_container.dart'; 9 | import 'package:odoo_common_code_latest/common/widgets/text_input.dart'; 10 | 11 | class SignIn extends StatefulWidget { 12 | @override 13 | _SignInState createState() => _SignInState(); 14 | } 15 | 16 | class _SignInState extends State { 17 | final TextEditingController _emailController = TextEditingController(); 18 | final TextEditingController _passCtrl = TextEditingController(); 19 | 20 | @override 21 | void initState() { 22 | super.initState(); 23 | getVersionInfoAPI(); 24 | } 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | return MainContainer( 29 | isAppBar: true, 30 | appBarTitle: Localize.signin.tr, 31 | padding: 20.0, 32 | child: Column( 33 | crossAxisAlignment: CrossAxisAlignment.center, 34 | mainAxisAlignment: MainAxisAlignment.center, 35 | children: [ 36 | SizedBox( 37 | height: MediaQuery.of(context).size.height / 4, 38 | ), 39 | TextInput( 40 | textInputAction: TextInputAction.next, 41 | borderRadius: BorderRadius.circular(10.0), 42 | controller: _emailController, 43 | textInputType: TextInputType.emailAddress, 44 | hintText: Localize.email.tr, 45 | ), 46 | SizedBox( 47 | height: 12, 48 | ), 49 | TextInput( 50 | borderRadius: BorderRadius.circular(10.0), 51 | controller: _passCtrl, 52 | isPassword: true, 53 | hintText: Localize.password.tr, 54 | ), 55 | SizedBox( 56 | height: 17, 57 | ), 58 | SizedBox( 59 | height: 55, 60 | child: CustomButton( 61 | color: AppColors.orange, 62 | onPress: () { 63 | FocusManager.instance.primaryFocus!.unfocus(); 64 | if (_emailController.text.isEmpty) { 65 | showWarning("Please enter email"); 66 | } else if (_passCtrl.text.isEmpty) { 67 | showWarning("Please enter password"); 68 | } else { 69 | authenticationAPI(_emailController.text, _passCtrl.text); 70 | } 71 | }, 72 | child: Text( 73 | Localize.signin.tr, 74 | style: TextStyle( 75 | color: Colors.white, 76 | fontWeight: FontWeight.normal, 77 | fontSize: 17, 78 | ), 79 | ), 80 | ), 81 | ), 82 | ], 83 | ), 84 | ); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /lib/common/config/extentions.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:intl/intl.dart'; 4 | 5 | extension MyString on String { 6 | String get first => this[0]; 7 | 8 | String get last => this[this.length - 1]; 9 | 10 | String get capitalize => "${this[0].toUpperCase()}${this.substring(1)}"; 11 | 12 | String get trimMobile => this.replaceAll(" ", ""); 13 | 14 | String get setDefaultVal => 15 | (this.trim() == "") ? "..." : this; 16 | 17 | String get setPerc => this.trim() == "" ? "" : '$this%'; 18 | 19 | String get setNAVal => this.trim() == "" ? "N/A" : this; 20 | 21 | bool get isNullOrEmpty => (this.trim() == "") ? true : false; 22 | 23 | String get setChatId => (this.trim() == "") ? this : 'c$this'; 24 | 25 | int? get toInt => this.trim() == "" ? null : int.parse(this); 26 | 27 | Image image({color: Color}) { 28 | return Image.asset( 29 | this, 30 | color: color, 31 | ); 32 | } 33 | 34 | CachedNetworkImage cachedImage( 35 | {double? height, double? width, BoxFit? fit, String? placeholder}) => 36 | CachedNetworkImage( 37 | fit: fit ?? BoxFit.fill, 38 | height: height ?? 20.0, 39 | width: width ?? 20.0, 40 | imageUrl: this, 41 | progressIndicatorBuilder: (context, url, downloadProgress) => 42 | CircularProgressIndicator(value: downloadProgress.progress), 43 | errorWidget: (context, url, error) => placeholder != null 44 | ? Image.asset(placeholder, fit: BoxFit.fill) 45 | : Icon(Icons.error), 46 | ); 47 | 48 | String setKVal() { 49 | return '$this k'; 50 | } 51 | 52 | String withCompany(String company) { 53 | if (!this.isNullOrEmpty && !company.isNullOrEmpty) { 54 | return this + ' at ' + company; 55 | } else if (!this.isNullOrEmpty) { 56 | return this; 57 | } else if (!company.isNullOrEmpty) { 58 | return company; 59 | } else { 60 | return this.setDefaultVal; 61 | } 62 | } 63 | } 64 | 65 | extension MyInt on int { 66 | bool get boolType => this == 0 ? false : true; 67 | 68 | String get setDigit => NumberFormat.compactCurrency( 69 | decimalDigits: 0, 70 | symbol: 71 | '', // if you want to add currency symbol then pass that in this else leave it empty. 72 | ).format(this ?? 0); 73 | 74 | String get setMonths => (this != null) 75 | ? this.toString() + ' months' 76 | : this.toString().setDefaultVal; 77 | 78 | String setFormatted(int val) { 79 | return NumberFormat.currency(symbol: "", decimalDigits: 0).format(val); 80 | } 81 | 82 | String setKVal() { 83 | var val = this ?? 0; 84 | return '$val\k'; 85 | } 86 | 87 | String setPayscale() { 88 | var val = this ?? 0; 89 | return '${setFormatted(this)}/pm'; 90 | } 91 | } 92 | 93 | extension MyDateTime on DateTime { 94 | String get getAgeInYears { 95 | int ageInteger = 0; 96 | 97 | if (this != null) { 98 | DateTime today = DateTime.now(); 99 | today = DateTime(today.year, today.month, today.day); 100 | DateTime dob = DateTime(this.year, this.month, this.day); 101 | 102 | ageInteger = today.year - dob.year; 103 | 104 | if (today.month == dob.month) { 105 | if (today.day < dob.day) { 106 | ageInteger = ageInteger - 1; 107 | } 108 | } else if (today.month < dob.month) { 109 | ageInteger = ageInteger - 1; 110 | } 111 | } 112 | return ageInteger.toString() + ' yr'; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /.flutter-plugins-dependencies: -------------------------------------------------------------------------------- 1 | {"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"device_info_plus","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\device_info_plus-9.0.1\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.2.3\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.2.2\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.2.8+4\\\\","native_build":true,"dependencies":[]}],"android":[{"name":"device_info_plus","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\device_info_plus-9.0.1\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_android-2.0.27\\\\","native_build":true,"dependencies":[]},{"name":"shared_preferences_android","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_android-2.1.4\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.2.8+4\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"device_info_plus","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\device_info_plus-9.0.1\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.2.3\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.2.2\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.2.8+4\\\\","native_build":true,"dependencies":[]}],"linux":[{"name":"device_info_plus","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\device_info_plus-9.0.1\\\\","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.1.11\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_linux-2.2.0\\\\","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"device_info_plus","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\device_info_plus-9.0.1\\\\","native_build":false,"dependencies":[]},{"name":"path_provider_windows","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.1.6\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_windows-2.2.0\\\\","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"device_info_plus","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\device_info_plus-9.0.1\\\\","dependencies":[]},{"name":"shared_preferences_web","path":"C:\\\\Users\\\\lokha\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_web-2.1.0\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"device_info_plus","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"sqflite","dependencies":[]}],"date_created":"2023-05-25 22:27:36.979710","version":"3.10.2"} -------------------------------------------------------------------------------- /lib/common/widgets/date_picker.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:get/get.dart'; 4 | import 'package:odoo_common_code_latest/common/config/localization/localize.dart'; 5 | 6 | typedef void OnDateChange(DateTime dateTime); 7 | typedef void OnTimeChange(TimeOfDay dateTime); 8 | 9 | class DatePicker { 10 | DatePicker(); 11 | 12 | var selectedDate = DateTime.now(); 13 | OnDateChange? onDateChange; 14 | var datePickerMode; 15 | 16 | show(BuildContext context, 17 | {minimumDate, 18 | maximumDate, 19 | onDateChange, 20 | onTimeChange, 21 | selectedDate, 22 | datePickerMode}) async { 23 | final ThemeData theme = Theme.of(context); 24 | switch (theme.platform) { 25 | case TargetPlatform.android: 26 | case TargetPlatform.fuchsia: 27 | case TargetPlatform.linux: 28 | case TargetPlatform.windows: 29 | return _buildMaterialDatePicker(context, onDateChange, onTimeChange, 30 | minimumDate, maximumDate, selectedDate, datePickerMode); 31 | case TargetPlatform.iOS: 32 | case TargetPlatform.macOS: 33 | return _buildCupertinoDatePicker(context, onDateChange, minimumDate, 34 | maximumDate, selectedDate, datePickerMode); 35 | } 36 | } 37 | 38 | /// This builds material date picker in Android 39 | _buildMaterialDatePicker( 40 | BuildContext context, 41 | OnDateChange onDateChange, 42 | OnTimeChange onTimeChange, 43 | DateTime? minimumDate, 44 | DateTime? maximumDate, 45 | DateTime? selectedDate, 46 | var datePickerMode) async { 47 | DateTime? picked = await showDatePicker( 48 | context: context, 49 | initialDate: selectedDate ?? this.selectedDate, 50 | firstDate: minimumDate ?? DateTime(2000), 51 | lastDate: maximumDate ?? DateTime(2050), 52 | builder: (context, child) { 53 | return Theme( 54 | data: ThemeData.light(), 55 | child: child ?? Container(), 56 | ); 57 | }, 58 | ); 59 | if (picked != null) { 60 | this.selectedDate = picked; 61 | if (datePickerMode == true) { 62 | onDateChange(picked); 63 | _buildTimePicker(context, onTimeChange); 64 | } else { 65 | onDateChange(picked); 66 | } 67 | } 68 | } 69 | 70 | _buildTimePicker(BuildContext context, OnTimeChange onTimeChange) async { 71 | final TimeOfDay picked = 72 | await showTimePicker(context: context, initialTime: TimeOfDay.now()) ?? 73 | TimeOfDay.now(); 74 | onTimeChange(picked); 75 | } 76 | 77 | /// This builds cupertion date picker in iOS 78 | _buildCupertinoDatePicker( 79 | BuildContext context, 80 | OnDateChange onDateChange, 81 | DateTime? minimumDate, 82 | DateTime? maximumDate, 83 | DateTime? selectedDate, 84 | var datePickerMode) { 85 | showModalBottomSheet( 86 | context: context, 87 | builder: (BuildContext builder) { 88 | return Container( 89 | height: MediaQuery.of(context).copyWith().size.height / 3, 90 | color: Colors.white, 91 | child: Column( 92 | children: [ 93 | Padding( 94 | padding: EdgeInsets.only(left: 10.0, right: 10.0), 95 | child: Expanded( 96 | child: Row( 97 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 98 | crossAxisAlignment: CrossAxisAlignment.center, 99 | children: [ 100 | TextButton( 101 | onPressed: () { 102 | onDateChange(this.selectedDate); 103 | Navigator.pop(context); 104 | }, 105 | child: Text(Localize.done.tr), 106 | ), 107 | TextButton( 108 | onPressed: () { 109 | Navigator.pop(context); 110 | }, 111 | child: Text(Localize.cancel.tr), 112 | ), 113 | ], 114 | ), 115 | ), 116 | ), 117 | Expanded( 118 | child: CupertinoDatePicker( 119 | mode: datePickerMode ?? CupertinoDatePickerMode.date, 120 | onDateTimeChanged: (picked) { 121 | this.selectedDate = picked; 122 | onDateChange(picked); 123 | }, 124 | initialDateTime: selectedDate ?? this.selectedDate, 125 | minimumDate: minimumDate ?? DateTime(2000), 126 | maximumDate: maximumDate ?? DateTime(2050), 127 | ), 128 | ), 129 | ], 130 | ), 131 | ); 132 | }, 133 | ); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /lib/common/config/app_fonts.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:odoo_common_code_latest/common/config/app_colors.dart'; 3 | 4 | class AppFont { 5 | AppFont._(); 6 | 7 | static const Roboto_Black = 'RobotoBlack'; 8 | static const Roboto_BlackItalic = 'RobotoBlackItalic'; 9 | static const Roboto_Bold = 'RobotoBold'; 10 | static const Roboto_BoldItalic = 'RobotoBoldItalic'; 11 | static const Roboto_Italic = 'RobotoItalic'; 12 | static const Roboto_Light = 'RobotoLight'; 13 | static const Roboto_LightItalic = 'RobotoLightItalic'; 14 | static const Roboto_Medium = 'RobotoMedium'; 15 | static const Roboto_MediumItalic = 'RobotoMediumItalic'; 16 | static const Roboto_Regular = 'RobotoRegular'; 17 | static const Roboto_Thin = 'RobotoThin'; 18 | static const Roboto_ThinItalic = 'RobotoThinItalic'; 19 | 20 | static TextStyle Title_H2_Medium({Color? color, double? size}) { 21 | return TextStyle( 22 | color: color ?? AppColors.black, 23 | fontFamily: Roboto_Medium, 24 | //fontStyle: FontStyle.normal, 25 | //fontWeight: FontWeight.w500, 26 | fontSize: size ?? 60, 27 | ); 28 | } 29 | 30 | static TextStyle Title_H3_Medium({Color? color, double? size}) { 31 | return TextStyle( 32 | color: color ?? AppColors.black, 33 | fontFamily: Roboto_Medium, 34 | //fontStyle: FontStyle.normal, 35 | //fontWeight: FontWeight.w500, 36 | fontSize: size ?? 48, 37 | ); 38 | } 39 | 40 | static TextStyle Title_H4_Medium({Color? color, double? size}) { 41 | return TextStyle( 42 | color: color ?? AppColors.black, 43 | fontFamily: Roboto_Medium, 44 | //fontStyle: FontStyle.normal, 45 | //fontWeight: FontWeight.w500, 46 | fontSize: size ?? 30, 47 | ); 48 | } 49 | 50 | static TextStyle Title_H4_Regular({Color? color, double? size}) { 51 | return TextStyle( 52 | color: color ?? AppColors.black, 53 | fontFamily: Roboto_Light, 54 | //fontStyle: FontStyle.normal, 55 | //fontWeight: FontWeight.w500, 56 | fontSize: size ?? 30, 57 | ); 58 | } 59 | 60 | static TextStyle Title_H5_Medium({Color? color, double? size}) { 61 | return TextStyle( 62 | color: color ?? AppColors.black, 63 | fontFamily: Roboto_Medium, 64 | //fontStyle: FontStyle.normal, 65 | //fontWeight: FontWeight.w500, 66 | fontSize: size ?? 24, 67 | ); 68 | } 69 | 70 | static TextStyle Title_H6_Medium({Color? color, double? size}) { 71 | return TextStyle( 72 | color: color ?? AppColors.black, 73 | fontFamily: Roboto_Medium, 74 | //fontStyle: FontStyle.normal, 75 | //fontWeight: FontWeight.w500, 76 | fontSize: size ?? 20, 77 | ); 78 | } 79 | 80 | static TextStyle SubTitle1_Medium({Color? color, double? size}) { 81 | return TextStyle( 82 | color: color ?? AppColors.black, 83 | fontFamily: Roboto_Medium, 84 | //fontStyle: FontStyle.normal, 85 | //fontWeight: FontWeight.w500, 86 | fontSize: size ?? 17, 87 | ); 88 | } 89 | 90 | static TextStyle SubTitle2_Medium({Color? color, double? size}) { 91 | return TextStyle( 92 | color: color ?? AppColors.black, 93 | fontFamily: Roboto_Medium, 94 | //fontStyle: FontStyle.normal, 95 | //fontWeight: FontWeight.w500, 96 | fontSize: size ?? 15, 97 | ); 98 | } 99 | 100 | static TextStyle Body1_Regular({Color? color, double? size}) { 101 | return TextStyle( 102 | color: color ?? AppColors.black, 103 | fontFamily: Roboto_Regular, 104 | //fontStyle: FontStyle.normal, 105 | //fontWeight: FontWeight.normal, 106 | fontSize: size ?? 17, 107 | ); 108 | } 109 | 110 | static TextStyle Body2_Regular({Color? color, double? size}) { 111 | return TextStyle( 112 | color: color ?? AppColors.black, 113 | fontFamily: Roboto_Regular, 114 | // fontStyle: FontStyle.normal, 115 | // fontWeight: FontWeight.normal, 116 | fontSize: size ?? 15, 117 | ); 118 | } 119 | 120 | static TextStyle Caption1_Body({Color? color, double? size}) { 121 | return TextStyle( 122 | color: color ?? AppColors.black, 123 | fontFamily: Roboto_Regular, 124 | //fontStyle: FontStyle.normal, 125 | //fontWeight: FontWeight.normal, 126 | fontSize: size ?? 13, 127 | ); 128 | } 129 | 130 | static TextStyle Caption2_Title({Color? color, double? size}) { 131 | return TextStyle( 132 | color: color ?? AppColors.black, 133 | fontFamily: Roboto_Medium, 134 | //fontStyle: FontStyle.normal, 135 | //fontWeight: FontWeight.normal, 136 | fontSize: size ?? 12, 137 | ); 138 | } 139 | 140 | static TextStyle Caption2_Body({Color? color, double? size}) { 141 | return TextStyle( 142 | color: color ?? AppColors.black, 143 | fontFamily: Roboto_Regular, 144 | //fontStyle: FontStyle.normal, 145 | //fontWeight: FontWeight.normal, 146 | fontSize: size ?? 12, 147 | ); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /lib/common/widgets/text_input.dart: -------------------------------------------------------------------------------- 1 | import 'package:country_code_picker/country_code_picker.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:odoo_common_code_latest/common/config/app_colors.dart'; 4 | 5 | typedef void OnChangeCountryCode(CountryCode countryCode); 6 | typedef void OnFieldSubmitted(String text); 7 | 8 | class TextInput extends StatelessWidget { 9 | TextEditingController controller; 10 | String? validationMsg, 11 | hintText, 12 | labelText, 13 | helperText, 14 | prefixText, 15 | suffixText; 16 | Widget? prefix, suffix; 17 | int? maxLength; 18 | bool? isPassword, countryCodeEnabled, isEnabled; 19 | bool? isSimpleField; 20 | BorderRadius? borderRadius; 21 | TextInputType? textInputType; 22 | OnChangeCountryCode? onChangeCountryCode; 23 | TextInputAction? textInputAction; 24 | OnFieldSubmitted? onFieldSubmitted; 25 | FocusNode? focusNode; 26 | 27 | TextInput( 28 | {this.validationMsg, 29 | required this.controller, 30 | this.helperText, 31 | this.suffixText, 32 | this.prefixText, 33 | this.prefix, 34 | this.labelText, 35 | this.hintText, 36 | this.suffix, 37 | this.textInputType, 38 | this.isPassword, 39 | this.maxLength, 40 | this.countryCodeEnabled, 41 | this.borderRadius, 42 | this.isSimpleField, 43 | this.onChangeCountryCode, 44 | this.textInputAction, 45 | this.onFieldSubmitted, 46 | this.focusNode, 47 | this.isEnabled}); 48 | 49 | @override 50 | Widget build(BuildContext context) { 51 | return TextFormField( 52 | minLines: 1, 53 | maxLines: isPassword != null && isPassword == true ? 1 : 4, 54 | onFieldSubmitted: (value) => 55 | onFieldSubmitted != null ? onFieldSubmitted!(value) : null, 56 | focusNode: focusNode ?? null, 57 | readOnly: isEnabled ?? false, 58 | style: TextStyle( 59 | fontSize: 17, 60 | color: AppColors.black, 61 | fontWeight: FontWeight.normal, 62 | ), 63 | controller: controller, 64 | validator: (String? value) { 65 | if (value == null) return null; 66 | return value.isEmpty ? validationMsg ?? null : null; 67 | }, 68 | maxLength: maxLength ?? null, 69 | obscureText: isPassword ?? false, 70 | keyboardType: textInputType ?? TextInputType.text, 71 | textInputAction: textInputAction ?? null, 72 | decoration: isSimpleField == true 73 | // For Under border input field 74 | ? InputDecoration( 75 | enabledBorder: UnderlineInputBorder( 76 | borderSide: BorderSide(width: 1, color: AppColors.borderColor), 77 | ), 78 | hintStyle: TextStyle( 79 | fontSize: 17, 80 | color: AppColors.lightGrey, 81 | fontWeight: FontWeight.normal, 82 | ), 83 | labelStyle: TextStyle( 84 | fontSize: 17, 85 | color: AppColors.lightGrey, 86 | fontWeight: FontWeight.normal, 87 | height: 0, 88 | ), 89 | hintText: hintText ?? null, 90 | helperText: helperText ?? null, 91 | labelText: labelText ?? null, 92 | prefixIcon: prefix ?? null, 93 | suffixIcon: suffix ?? null, 94 | prefixText: prefixText ?? null, 95 | suffixText: suffixText ?? null, 96 | counterText: "", 97 | prefix: countryCodeEnabled == true 98 | ? CountryCodePicker( 99 | onChanged: (countryCode) { 100 | onChangeCountryCode!(countryCode); 101 | }, 102 | initialSelection: 'IN', 103 | showCountryOnly: true, 104 | showOnlyCountryWhenClosed: false, 105 | alignLeft: false, 106 | ) 107 | : null, 108 | ) 109 | // For Outlined border input field 110 | : InputDecoration( 111 | fillColor: AppColors.textFieldBackgroundColor, 112 | filled: true, 113 | enabledBorder: OutlineInputBorder( 114 | borderRadius: borderRadius ?? BorderRadius.circular(5.0), 115 | borderSide: BorderSide(width: 1, color: AppColors.borderColor), 116 | ), 117 | border: OutlineInputBorder( 118 | borderRadius: borderRadius ?? BorderRadius.circular(5.0), 119 | borderSide: BorderSide( 120 | width: 1, 121 | ), 122 | ), 123 | hintStyle: TextStyle( 124 | fontSize: 17, 125 | color: AppColors.lightGrey, 126 | fontWeight: FontWeight.normal, 127 | ), 128 | labelStyle: TextStyle( 129 | fontSize: 17, 130 | color: AppColors.lightGrey, 131 | fontWeight: FontWeight.normal, 132 | ), 133 | hintText: hintText ?? null, 134 | helperText: helperText ?? null, 135 | labelText: labelText ?? null, 136 | prefixIcon: prefix ?? null, 137 | suffixIcon: suffix ?? null, 138 | prefixText: prefixText ?? null, 139 | suffixText: suffixText ?? null, 140 | counterText: "", 141 | prefix: countryCodeEnabled == true 142 | ? CountryCodePicker( 143 | onChanged: (countryCode) { 144 | onChangeCountryCode!(countryCode); 145 | }, 146 | initialSelection: 'IN', 147 | showCountryOnly: true, 148 | showOnlyCountryWhenClosed: false, 149 | alignLeft: false, 150 | ) 151 | : null, 152 | ), 153 | ); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /lib/common/utils/utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | import 'package:odoo_common_code_latest/common/api_factory/models/base_list.dart'; 4 | import 'package:odoo_common_code_latest/common/api_factory/modules/authentication_module.dart'; 5 | import 'package:odoo_common_code_latest/common/config/app_colors.dart'; 6 | import 'package:odoo_common_code_latest/common/config/app_fonts.dart'; 7 | import 'package:odoo_common_code_latest/common/config/app_images.dart'; 8 | import 'package:odoo_common_code_latest/common/config/config.dart'; 9 | import 'package:odoo_common_code_latest/common/config/localization/localize.dart'; 10 | import 'package:odoo_common_code_latest/common/config/prefs/pref_utils.dart'; 11 | import 'package:odoo_common_code_latest/common/widgets/log.dart'; 12 | 13 | Future ackAlert( 14 | BuildContext context, 15 | String title, 16 | String content, 17 | VoidCallback onPressed, 18 | ) { 19 | return showDialog( 20 | context: context, 21 | builder: (BuildContext context) { 22 | return AlertDialog( 23 | title: Text(title), 24 | titleTextStyle: TextStyle( 25 | fontFamily: AppFont.Roboto_Regular, 26 | fontSize: 21, 27 | color: Colors.black, 28 | fontWeight: FontWeight.bold, 29 | ), 30 | content: Text(content), 31 | contentTextStyle: TextStyle( 32 | fontFamily: AppFont.Roboto_Regular, 33 | fontSize: 17, 34 | color: Colors.black, 35 | fontWeight: FontWeight.w500, 36 | ), 37 | actions: [ 38 | TextButton( 39 | child: Text( 40 | Localize.done.tr, 41 | style: TextStyle( 42 | fontFamily: AppFont.Roboto_Regular, 43 | fontSize: 17, 44 | color: AppColors.blue, 45 | fontWeight: FontWeight.bold, 46 | ), 47 | ), 48 | onPressed: onPressed, 49 | ), 50 | ], 51 | ); 52 | }, 53 | ); 54 | } 55 | 56 | showLoading() { 57 | Get.dialog( 58 | Center( 59 | child: SizedBox( 60 | child: FittedBox(child: CircularProgressIndicator()), 61 | height: 50.0, 62 | width: 50.0, 63 | ), 64 | ), 65 | barrierDismissible: false, 66 | ); 67 | } 68 | 69 | hideLoading() { 70 | Get.back(); 71 | } 72 | 73 | void showSnackBar( 74 | {title, 75 | message, 76 | SnackPosition? snackPosition, 77 | Color? backgroundColor, 78 | Duration? duration}) { 79 | Get.showSnackbar( 80 | GetBar( 81 | title: title, 82 | message: message, 83 | duration: duration ?? Duration(seconds: 2), 84 | snackPosition: snackPosition ?? SnackPosition.BOTTOM, 85 | backgroundColor: backgroundColor ?? Colors.black87, 86 | ), 87 | ); 88 | } 89 | 90 | handleApiError(errorMessage) { 91 | showSnackBar(backgroundColor: Colors.redAccent, message: errorMessage); 92 | } 93 | 94 | showWarning(message) { 95 | showSnackBar(backgroundColor: Colors.blueAccent, message: message); 96 | } 97 | 98 | bool validatePassword(String password) { 99 | return RegExp( 100 | r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\$&*~?]).{8,}$') 101 | .hasMatch(password); 102 | } 103 | 104 | bool validateEmail(String email) { 105 | return RegExp( 106 | r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+") 107 | .hasMatch(email); 108 | } 109 | 110 | bool validURL(String url) { 111 | return Uri.parse(url).isAbsolute; 112 | } 113 | 114 | typedef OnItemsSelected(BaseListModel data); 115 | typedef OnMultiItemSelected(List data); 116 | typedef OnFilterSelected(String salary); 117 | 118 | //MARK - Open single select bottomsheet - 119 | //----------------------------------- 120 | showCustomBottomSheet({ 121 | @required List? list, 122 | @required String? title, 123 | @required OnItemsSelected? onItemsSelected, 124 | bool isMultiSelect = false, 125 | }) { 126 | Get.bottomSheet( 127 | BottomSheet( 128 | shape: RoundedRectangleBorder( 129 | borderRadius: BorderRadius.only( 130 | topRight: Radius.circular(30.0), 131 | topLeft: Radius.circular(30.0), 132 | ), 133 | ), 134 | onClosing: () { 135 | Log("on Close bottom sheet"); 136 | }, 137 | builder: (context) { 138 | return Container( 139 | decoration: BoxDecoration( 140 | borderRadius: BorderRadius.only( 141 | topRight: Radius.circular(30.0), 142 | topLeft: Radius.circular(30.0), 143 | ), 144 | ), 145 | padding: EdgeInsets.all(16.0), 146 | child: Column( 147 | crossAxisAlignment: CrossAxisAlignment.center, 148 | children: [ 149 | Container( 150 | width: 40, 151 | height: 4, 152 | color: AppColors.greyDotColor, 153 | ), 154 | SizedBox( 155 | height: 25, 156 | ), 157 | Row( 158 | children: [ 159 | InkWell( 160 | onTap: () { 161 | Get.back(); 162 | }, 163 | child: Image.asset(AppImages.ic_back), 164 | ), 165 | SizedBox( 166 | width: 25, 167 | ), 168 | Text( 169 | title ?? "", 170 | style: AppFont.Title_H6_Medium(), 171 | ), 172 | isMultiSelect 173 | ? Expanded( 174 | child: Align( 175 | alignment: Alignment.centerRight, 176 | child: SizedBox( 177 | height: 41, 178 | width: 75, 179 | child: MaterialButton( 180 | elevation: 0.0, 181 | color: AppColors.blueButtonColor, 182 | onPressed: () { 183 | var isSelectedItems = 184 | list!.where((e) => e.isSelected).toList(); 185 | if (isSelectedItems.length == 0) { 186 | // showWarning(Localize.selectAnyItem.tr); 187 | } else { 188 | Get.back(result: isSelectedItems); 189 | } 190 | }, 191 | child: Text( 192 | Localize.done.tr, 193 | style: TextStyle( 194 | color: Colors.white, 195 | fontWeight: FontWeight.normal, 196 | fontSize: 17, 197 | ), 198 | ), 199 | textColor: AppColors.black, 200 | shape: RoundedRectangleBorder( 201 | borderRadius: BorderRadius.circular(8), 202 | ), 203 | ), 204 | ), 205 | ), 206 | ) 207 | : SizedBox(), 208 | ], 209 | ), 210 | SizedBox( 211 | height: 30, 212 | ), 213 | Expanded( 214 | child: Container( 215 | height: MediaQuery.of(context).size.height / 2 - 170, 216 | child: ListView.builder( 217 | shrinkWrap: true, 218 | physics: ScrollPhysics(), 219 | itemCount: list!.length, 220 | itemBuilder: (context, index) { 221 | return Container( 222 | height: 50, 223 | child: InkWell( 224 | child: Row( 225 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 226 | children: [ 227 | Text( 228 | list[index].name!, 229 | style: AppFont.Body1_Regular(), 230 | ), 231 | list[index].isSelected 232 | ? Icon(Icons.done) 233 | : SizedBox() 234 | ], 235 | ), 236 | onTap: () { 237 | if (isMultiSelect) { 238 | list[index].isSelected = !list[index].isSelected; 239 | } else { 240 | list[index].isSelected = !list[index].isSelected; 241 | Get.back(result: list[index]); 242 | } 243 | }, 244 | ), 245 | ); 246 | }, 247 | ), 248 | ), 249 | ) 250 | ], 251 | ), 252 | ); 253 | }, 254 | ), 255 | ).then((value) { 256 | FocusManager.instance.primaryFocus!.unfocus(); 257 | onItemsSelected!(value); 258 | Log(value); 259 | }); 260 | } 261 | 262 | showSessionDialog() { 263 | Get.dialog( 264 | AlertDialog( 265 | shape: RoundedRectangleBorder( 266 | borderRadius: BorderRadius.circular(16.0), 267 | ), 268 | title: Text( 269 | "Session Time out", 270 | style: AppFont.Title_H4_Medium(), 271 | ), 272 | content: Text( 273 | "Sorry! your session is expired, Please login again", 274 | style: AppFont.Body2_Regular(), 275 | ), 276 | actions: [ 277 | TextButton( 278 | onPressed: () async { 279 | PrefUtils.clearPrefs(); 280 | }, 281 | child: Text( 282 | Localize.signin.tr, 283 | style: AppFont.Body2_Regular(), 284 | ), 285 | ), 286 | ], 287 | ), 288 | ); 289 | } 290 | 291 | showLogoutDialog() { 292 | Get.dialog( 293 | AlertDialog( 294 | shape: RoundedRectangleBorder( 295 | borderRadius: BorderRadius.circular(16.0), 296 | ), 297 | title: Text( 298 | "Logout", 299 | style: AppFont.Title_H4_Medium(), 300 | ), 301 | content: Text( 302 | "Are you sure you want to logout?", 303 | style: AppFont.Body2_Regular(), 304 | ), 305 | actions: [ 306 | TextButton( 307 | onPressed: () async { 308 | Get.back(); 309 | }, 310 | child: Text( 311 | Localize.cancel.tr, 312 | style: AppFont.Body2_Regular(), 313 | ), 314 | ), 315 | TextButton( 316 | onPressed: () async { 317 | Get.back(); 318 | logoutApi(); 319 | }, 320 | child: Text( 321 | "Logout", 322 | style: AppFont.Body2_Regular(), 323 | ), 324 | ), 325 | ], 326 | ), 327 | ); 328 | } 329 | 330 | Future getImageUrl( 331 | {required String model, required String field, required String id}) async { 332 | String session = await PrefUtils.getToken(); 333 | return Config.OdooDevURL + 334 | "/web/image?model=$model&field=$field&$session&id=$id"; 335 | } 336 | -------------------------------------------------------------------------------- /lib/common/api_factory/api.dart: -------------------------------------------------------------------------------- 1 | import 'package:dio/dio.dart'; 2 | import 'package:flutter/foundation.dart'; 3 | import 'package:odoo_common_code_latest/common/api_factory/api_end_points.dart'; 4 | import 'package:odoo_common_code_latest/common/api_factory/dio_factory.dart'; 5 | import 'package:odoo_common_code_latest/common/api_factory/models/version_info_response.dart'; 6 | import 'package:odoo_common_code_latest/common/config/config.dart'; 7 | import 'package:odoo_common_code_latest/common/config/prefs/pref_utils.dart'; 8 | import 'package:odoo_common_code_latest/common/utils/utils.dart'; 9 | import 'package:odoo_common_code_latest/common/widgets/log.dart'; 10 | import 'package:odoo_common_code_latest/src/authentication/models/user_model.dart'; 11 | import 'package:uuid/uuid.dart'; 12 | 13 | enum ApiEnvironment { UAT, Dev, Prod } 14 | 15 | extension APIEnvi on ApiEnvironment { 16 | String get endpoint { 17 | switch (this) { 18 | case ApiEnvironment.UAT: 19 | return Config.OdooUATURL; 20 | case ApiEnvironment.Dev: 21 | return Config.OdooDevURL; 22 | case ApiEnvironment.Prod: 23 | return Config.OdooProdURL; 24 | } 25 | } 26 | } 27 | 28 | enum HttpMethod { delete, get, patch, post, put } 29 | 30 | extension HttpMethods on HttpMethod { 31 | String get value { 32 | switch (this) { 33 | case HttpMethod.delete: 34 | return 'DELETE'; 35 | case HttpMethod.get: 36 | return 'GET'; 37 | case HttpMethod.patch: 38 | return 'PATCH'; 39 | case HttpMethod.post: 40 | return 'POST'; 41 | case HttpMethod.put: 42 | return 'PUT'; 43 | } 44 | } 45 | } 46 | 47 | class Api { 48 | Api._(); 49 | 50 | static final catchError = _catchError; 51 | 52 | static void _catchError(e, stackTrace, OnError onError) { 53 | if (!kReleaseMode) { 54 | print(e); 55 | } 56 | if (e is DioError) { 57 | if (e.type == DioErrorType.connectionTimeout || 58 | e.type == DioErrorType.sendTimeout || 59 | e.type == DioErrorType.receiveTimeout || 60 | e.type == DioErrorType.unknown) { 61 | onError('Server unreachable', {}); 62 | } else if (e.type == DioErrorType.badResponse) { 63 | final response = e.response; 64 | if (response != null) { 65 | final data = response.data; 66 | if (data != null && data is Map) { 67 | showSessionDialog(); 68 | onError('Failed to get response: ${e.message}', data); 69 | return; 70 | } 71 | } 72 | onError('Failed to get response: ${e.message}', {}); 73 | } else { 74 | onError('Request cancelled', {}); 75 | } 76 | } else { 77 | onError(e?.toString() ?? 'Unknown error occurred', {}); 78 | } 79 | } 80 | 81 | //General Post Request 82 | static Future request( 83 | {required HttpMethod method, 84 | required String path, 85 | required Map params, 86 | required OnResponse onResponse, 87 | required OnError onError}) async { 88 | Future.delayed(Duration(microseconds: 1), () { 89 | if (path != ApiEndPoints.getVersionInfo && 90 | path != ApiEndPoints.getDb && 91 | path != ApiEndPoints.getDb9 && 92 | path != ApiEndPoints.getDb10) showLoading(); 93 | }); 94 | 95 | Response response; 96 | switch (method) { 97 | case HttpMethod.post: 98 | response = await DioFactory.dio! 99 | .post( 100 | path, 101 | data: params, 102 | ) 103 | .catchError((e, stackTrace) => _catchError(e, stackTrace, onError)); 104 | break; 105 | case HttpMethod.delete: 106 | response = await DioFactory.dio! 107 | .delete( 108 | path, 109 | data: params, 110 | ) 111 | .catchError((e, stackTrace) => _catchError(e, stackTrace, onError)); 112 | break; 113 | case HttpMethod.get: 114 | response = await DioFactory.dio! 115 | .get( 116 | path, 117 | ) 118 | .catchError((e, stackTrace) => _catchError(e, stackTrace, onError)); 119 | break; 120 | case HttpMethod.patch: 121 | response = await DioFactory.dio! 122 | .patch( 123 | path, 124 | data: params, 125 | ) 126 | .catchError((e, stackTrace) => _catchError(e, stackTrace, onError)); 127 | break; 128 | case HttpMethod.put: 129 | response = await DioFactory.dio! 130 | .put( 131 | path, 132 | data: params, 133 | ) 134 | .catchError((e, stackTrace) => _catchError(e, stackTrace, onError)); 135 | break; 136 | } 137 | 138 | hideLoading(); 139 | if (response.data["success"] == 0) { 140 | onError(response.data["error"][0], {}); 141 | } else { 142 | onResponse(response.data["result"]); 143 | } 144 | 145 | if (path == ApiEndPoints.authenticate) { 146 | _updateCookies(response.headers); 147 | } 148 | } 149 | 150 | static _updateCookies(Headers headers) async { 151 | Log("Inside Update Cookie"); 152 | String? rawCookie = headers.value("set-cookie"); 153 | Log(rawCookie); 154 | if (rawCookie != null) { 155 | DioFactory.initialiseHeaders(rawCookie); 156 | PrefUtils.setToken(rawCookie); 157 | } 158 | } 159 | 160 | static getSessionInfo({ 161 | required OnResponse onResponse, 162 | required OnError onError, 163 | }) { 164 | request( 165 | method: HttpMethod.post, 166 | path: ApiEndPoints.getSessionInfo, 167 | params: createPayload({}), 168 | onResponse: (response) { 169 | onResponse(response); 170 | }, 171 | onError: (error, data) { 172 | onError(error, {}); 173 | }, 174 | ); 175 | } 176 | 177 | static destroy({ 178 | required OnResponse onResponse, 179 | required OnError onError, 180 | }) { 181 | request( 182 | method: HttpMethod.post, 183 | path: ApiEndPoints.destroy, 184 | params: createPayload({}), 185 | onResponse: (response) { 186 | onResponse(response); 187 | }, 188 | onError: (error, data) { 189 | onError(error, {}); 190 | }, 191 | ); 192 | } 193 | 194 | // Authenticate user 195 | static authenticate({ 196 | required String username, 197 | required String password, 198 | required String database, 199 | required OnResponse onResponse, 200 | required OnError onError, 201 | }) { 202 | var params = { 203 | "db": database, 204 | "login": username, 205 | "password": password, 206 | "context": {} 207 | }; 208 | 209 | request( 210 | method: HttpMethod.post, 211 | path: ApiEndPoints.authenticate, 212 | params: createPayload(params), 213 | onResponse: (response) { 214 | onResponse(UserModel.fromJson(response)); 215 | }, 216 | onError: (error, data) { 217 | onError(error, {}); 218 | }, 219 | ); 220 | } 221 | 222 | static read({ 223 | required String model, 224 | required List ids, 225 | required List fields, 226 | dynamic kwargs, 227 | required OnResponse onResponse, 228 | required OnError onError, 229 | }) async { 230 | callKW( 231 | model: model, 232 | method: "read", 233 | args: [ids, fields], 234 | kwargs: kwargs ?? null, 235 | onResponse: onResponse, 236 | onError: onError); 237 | } 238 | 239 | static searchRead({ 240 | required String model, 241 | required List domain, 242 | required List fields, 243 | int offset = 0, 244 | int limit = 0, 245 | String order = "", 246 | required OnResponse onResponse, 247 | required OnError onError, 248 | }) async { 249 | var params = { 250 | "context": getContext(), 251 | "domain": domain, 252 | "fields": fields, 253 | "limit": limit, 254 | "model": model, 255 | "offset": offset, 256 | "sort": order 257 | }; 258 | request( 259 | method: HttpMethod.post, 260 | path: ApiEndPoints.searchRead, 261 | params: createPayload(params), 262 | onResponse: (response) { 263 | onResponse(response); 264 | }, 265 | onError: (error, data) { 266 | onError(error, {}); 267 | }, 268 | ); 269 | } 270 | 271 | // Call any model method with arguments 272 | static callKW({ 273 | required String model, 274 | required String method, 275 | required List args, 276 | dynamic kwargs, 277 | required OnResponse onResponse, 278 | required OnError onError, 279 | }) async { 280 | var params = { 281 | "model": model, 282 | "method": method, 283 | "args": args, 284 | "kwargs": kwargs ?? {}, 285 | "context": getContext(), 286 | }; 287 | request( 288 | method: HttpMethod.post, 289 | path: ApiEndPoints.getCallKWEndPoint(model, method), 290 | params: createPayload(params), 291 | onResponse: (response) { 292 | onResponse(response); 293 | }, 294 | onError: (error, data) { 295 | onError(error, {}); 296 | }, 297 | ); 298 | } 299 | 300 | // Create new record for model 301 | static create({ 302 | required String model, 303 | required Map values, 304 | dynamic kwargs, 305 | required OnResponse onResponse, 306 | required OnError onError, 307 | }) { 308 | callKW( 309 | model: model, 310 | method: "create", 311 | args: [values], 312 | kwargs: kwargs ?? null, 313 | onResponse: onResponse, 314 | onError: onError); 315 | } 316 | 317 | // Write record with ids and values 318 | static write({ 319 | required String model, 320 | required List ids, 321 | required Map values, 322 | required OnResponse onResponse, 323 | required OnError onError, 324 | }) { 325 | callKW( 326 | model: model, 327 | method: "write", 328 | args: [ids, values], 329 | onResponse: onResponse, 330 | onError: onError); 331 | } 332 | 333 | // Remove record from system 334 | static unlink({ 335 | required String model, 336 | required List ids, 337 | dynamic kwargs, 338 | required OnResponse onResponse, 339 | required OnError onError, 340 | }) async { 341 | callKW( 342 | model: model, 343 | method: "unlink", 344 | args: [ids], 345 | kwargs: kwargs ?? null, 346 | onResponse: onResponse, 347 | onError: onError); 348 | } 349 | 350 | // Call json controller 351 | static callController({ 352 | required String path, 353 | required Map params, 354 | required OnResponse onResponse, 355 | required OnError onError, 356 | }) async { 357 | request( 358 | method: HttpMethod.post, 359 | path: path, 360 | params: createPayload(params), 361 | onResponse: (response) { 362 | onResponse(response); 363 | }, 364 | onError: (error, data) { 365 | onError(error, {}); 366 | }, 367 | ); 368 | } 369 | 370 | // get version of odoo 371 | static getVersionInfo({ 372 | required OnResponse onResponse, 373 | required OnError onError, 374 | }) { 375 | request( 376 | method: HttpMethod.post, 377 | path: ApiEndPoints.getVersionInfo, 378 | params: createPayload({}), 379 | onResponse: (response) { 380 | onResponse(VersionInfoResponse.fromJson(response)); 381 | }, 382 | onError: (error, data) { 383 | onError(error, {}); 384 | }, 385 | ); 386 | } 387 | 388 | static getDatabases({ 389 | required int serverVersionNumber, 390 | required OnResponse onResponse, 391 | required OnError onError, 392 | }) async { 393 | var params = {}; 394 | var endPoint = ""; 395 | if (serverVersionNumber == 9) { 396 | params["method"] = "list"; 397 | params["service"] = "db"; 398 | params["args"] = []; 399 | endPoint = ApiEndPoints.getDb9; 400 | } else if (serverVersionNumber >= 10) { 401 | endPoint = ApiEndPoints.getDb10; 402 | params["context"] = {}; 403 | } else { 404 | endPoint = ApiEndPoints.getDb; 405 | params["context"] = {}; 406 | } 407 | request( 408 | method: HttpMethod.post, 409 | path: endPoint, 410 | params: createPayload(params), 411 | onResponse: (response) { 412 | onResponse(response); 413 | }, 414 | onError: (error, data) { 415 | onError(error, {}); 416 | }, 417 | ); 418 | } 419 | 420 | static hasRight({ 421 | required String model, 422 | required List right, 423 | dynamic kwargs, 424 | required OnResponse onResponse, 425 | required OnError onError, 426 | }) { 427 | callKW( 428 | model: model, 429 | method: "has_group", 430 | args: right, 431 | kwargs: kwargs ?? null, 432 | onResponse: onResponse, 433 | onError: onError); 434 | } 435 | 436 | static Map createPayload(Map params) { 437 | return { 438 | "id": new Uuid().v1(), 439 | "jsonrpc": "2.0", 440 | "method": "call", 441 | "params": params, 442 | }; 443 | } 444 | 445 | static Map getContext() { 446 | return {"lang": "en_US", "tz": "Europe/Brussels", "uid": Uuid().v1()}; 447 | } 448 | } 449 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | action_broadcast: 5 | dependency: "direct main" 6 | description: 7 | name: action_broadcast 8 | sha256: "50d508fc1ee9d1399b53ad2ebc47aa60f1c2d18d057c734c593fc0c45bdfaea5" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "3.0.2" 12 | async: 13 | dependency: transitive 14 | description: 15 | name: async 16 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "2.11.0" 20 | boolean_selector: 21 | dependency: transitive 22 | description: 23 | name: boolean_selector 24 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "2.1.1" 28 | cached_network_image: 29 | dependency: "direct main" 30 | description: 31 | name: cached_network_image 32 | sha256: fd3d0dc1d451f9a252b32d95d3f0c3c487bc41a75eba2e6097cb0b9c71491b15 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "3.2.3" 36 | cached_network_image_platform_interface: 37 | dependency: transitive 38 | description: 39 | name: cached_network_image_platform_interface 40 | sha256: bb2b8403b4ccdc60ef5f25c70dead1f3d32d24b9d6117cfc087f496b178594a7 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "2.0.0" 44 | cached_network_image_web: 45 | dependency: transitive 46 | description: 47 | name: cached_network_image_web 48 | sha256: b8eb814ebfcb4dea049680f8c1ffb2df399e4d03bf7a352c775e26fa06e02fa0 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "1.0.2" 52 | characters: 53 | dependency: transitive 54 | description: 55 | name: characters 56 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "1.3.0" 60 | clock: 61 | dependency: transitive 62 | description: 63 | name: clock 64 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 65 | url: "https://pub.dev" 66 | source: hosted 67 | version: "1.1.1" 68 | collection: 69 | dependency: transitive 70 | description: 71 | name: collection 72 | sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" 73 | url: "https://pub.dev" 74 | source: hosted 75 | version: "1.17.1" 76 | country_code_picker: 77 | dependency: "direct main" 78 | description: 79 | name: country_code_picker 80 | sha256: "92818885f0e47486539f80463b66f649970506a91dd3c0731ca3ba5308324a4d" 81 | url: "https://pub.dev" 82 | source: hosted 83 | version: "3.0.0" 84 | crypto: 85 | dependency: transitive 86 | description: 87 | name: crypto 88 | sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab 89 | url: "https://pub.dev" 90 | source: hosted 91 | version: "3.0.3" 92 | cupertino_icons: 93 | dependency: "direct main" 94 | description: 95 | name: cupertino_icons 96 | sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be 97 | url: "https://pub.dev" 98 | source: hosted 99 | version: "1.0.5" 100 | device_info_plus: 101 | dependency: "direct main" 102 | description: 103 | name: device_info_plus 104 | sha256: "499c61743e13909c13374a8c209075385858c614b9c0f2487b5f9995eeaf7369" 105 | url: "https://pub.dev" 106 | source: hosted 107 | version: "9.0.1" 108 | device_info_plus_platform_interface: 109 | dependency: transitive 110 | description: 111 | name: device_info_plus_platform_interface 112 | sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64 113 | url: "https://pub.dev" 114 | source: hosted 115 | version: "7.0.0" 116 | dio: 117 | dependency: "direct main" 118 | description: 119 | name: dio 120 | sha256: "347d56c26d63519552ef9a569f2a593dda99a81fdbdff13c584b7197cfe05059" 121 | url: "https://pub.dev" 122 | source: hosted 123 | version: "5.1.2" 124 | fake_async: 125 | dependency: transitive 126 | description: 127 | name: fake_async 128 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 129 | url: "https://pub.dev" 130 | source: hosted 131 | version: "1.3.1" 132 | ffi: 133 | dependency: transitive 134 | description: 135 | name: ffi 136 | sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99 137 | url: "https://pub.dev" 138 | source: hosted 139 | version: "2.0.2" 140 | file: 141 | dependency: transitive 142 | description: 143 | name: file 144 | sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" 145 | url: "https://pub.dev" 146 | source: hosted 147 | version: "6.1.4" 148 | flutter: 149 | dependency: "direct main" 150 | description: flutter 151 | source: sdk 152 | version: "0.0.0" 153 | flutter_blurhash: 154 | dependency: transitive 155 | description: 156 | name: flutter_blurhash 157 | sha256: "05001537bd3fac7644fa6558b09ec8c0a3f2eba78c0765f88912882b1331a5c6" 158 | url: "https://pub.dev" 159 | source: hosted 160 | version: "0.7.0" 161 | flutter_cache_manager: 162 | dependency: transitive 163 | description: 164 | name: flutter_cache_manager 165 | sha256: "32cd900555219333326a2d0653aaaf8671264c29befa65bbd9856d204a4c9fb3" 166 | url: "https://pub.dev" 167 | source: hosted 168 | version: "3.3.0" 169 | flutter_localizations: 170 | dependency: "direct main" 171 | description: flutter 172 | source: sdk 173 | version: "0.0.0" 174 | flutter_test: 175 | dependency: "direct dev" 176 | description: flutter 177 | source: sdk 178 | version: "0.0.0" 179 | flutter_web_plugins: 180 | dependency: transitive 181 | description: flutter 182 | source: sdk 183 | version: "0.0.0" 184 | get: 185 | dependency: "direct main" 186 | description: 187 | name: get 188 | sha256: "2ba20a47c8f1f233bed775ba2dd0d3ac97b4cf32fc17731b3dfc672b06b0e92a" 189 | url: "https://pub.dev" 190 | source: hosted 191 | version: "4.6.5" 192 | http: 193 | dependency: transitive 194 | description: 195 | name: http 196 | sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" 197 | url: "https://pub.dev" 198 | source: hosted 199 | version: "0.13.6" 200 | http_parser: 201 | dependency: transitive 202 | description: 203 | name: http_parser 204 | sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" 205 | url: "https://pub.dev" 206 | source: hosted 207 | version: "4.0.2" 208 | intl: 209 | dependency: "direct main" 210 | description: 211 | name: intl 212 | sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6 213 | url: "https://pub.dev" 214 | source: hosted 215 | version: "0.18.0" 216 | js: 217 | dependency: transitive 218 | description: 219 | name: js 220 | sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 221 | url: "https://pub.dev" 222 | source: hosted 223 | version: "0.6.7" 224 | matcher: 225 | dependency: transitive 226 | description: 227 | name: matcher 228 | sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" 229 | url: "https://pub.dev" 230 | source: hosted 231 | version: "0.12.15" 232 | material_color_utilities: 233 | dependency: transitive 234 | description: 235 | name: material_color_utilities 236 | sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 237 | url: "https://pub.dev" 238 | source: hosted 239 | version: "0.2.0" 240 | meta: 241 | dependency: transitive 242 | description: 243 | name: meta 244 | sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" 245 | url: "https://pub.dev" 246 | source: hosted 247 | version: "1.9.1" 248 | octo_image: 249 | dependency: transitive 250 | description: 251 | name: octo_image 252 | sha256: "107f3ed1330006a3bea63615e81cf637433f5135a52466c7caa0e7152bca9143" 253 | url: "https://pub.dev" 254 | source: hosted 255 | version: "1.0.2" 256 | path: 257 | dependency: transitive 258 | description: 259 | name: path 260 | sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" 261 | url: "https://pub.dev" 262 | source: hosted 263 | version: "1.8.3" 264 | path_provider: 265 | dependency: "direct main" 266 | description: 267 | name: path_provider 268 | sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2" 269 | url: "https://pub.dev" 270 | source: hosted 271 | version: "2.0.15" 272 | path_provider_android: 273 | dependency: transitive 274 | description: 275 | name: path_provider_android 276 | sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86" 277 | url: "https://pub.dev" 278 | source: hosted 279 | version: "2.0.27" 280 | path_provider_foundation: 281 | dependency: transitive 282 | description: 283 | name: path_provider_foundation 284 | sha256: "1995d88ec2948dac43edf8fe58eb434d35d22a2940ecee1a9fefcd62beee6eb3" 285 | url: "https://pub.dev" 286 | source: hosted 287 | version: "2.2.3" 288 | path_provider_linux: 289 | dependency: transitive 290 | description: 291 | name: path_provider_linux 292 | sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57 293 | url: "https://pub.dev" 294 | source: hosted 295 | version: "2.1.11" 296 | path_provider_platform_interface: 297 | dependency: transitive 298 | description: 299 | name: path_provider_platform_interface 300 | sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" 301 | url: "https://pub.dev" 302 | source: hosted 303 | version: "2.0.6" 304 | path_provider_windows: 305 | dependency: transitive 306 | description: 307 | name: path_provider_windows 308 | sha256: d3f80b32e83ec208ac95253e0cd4d298e104fbc63cb29c5c69edaed43b0c69d6 309 | url: "https://pub.dev" 310 | source: hosted 311 | version: "2.1.6" 312 | pedantic: 313 | dependency: transitive 314 | description: 315 | name: pedantic 316 | sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" 317 | url: "https://pub.dev" 318 | source: hosted 319 | version: "1.11.1" 320 | platform: 321 | dependency: transitive 322 | description: 323 | name: platform 324 | sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" 325 | url: "https://pub.dev" 326 | source: hosted 327 | version: "3.1.0" 328 | plugin_platform_interface: 329 | dependency: transitive 330 | description: 331 | name: plugin_platform_interface 332 | sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc" 333 | url: "https://pub.dev" 334 | source: hosted 335 | version: "2.1.4" 336 | process: 337 | dependency: transitive 338 | description: 339 | name: process 340 | sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" 341 | url: "https://pub.dev" 342 | source: hosted 343 | version: "4.2.4" 344 | rxdart: 345 | dependency: transitive 346 | description: 347 | name: rxdart 348 | sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" 349 | url: "https://pub.dev" 350 | source: hosted 351 | version: "0.27.7" 352 | shared_preferences: 353 | dependency: "direct main" 354 | description: 355 | name: shared_preferences 356 | sha256: "16d3fb6b3692ad244a695c0183fca18cf81fd4b821664394a781de42386bf022" 357 | url: "https://pub.dev" 358 | source: hosted 359 | version: "2.1.1" 360 | shared_preferences_android: 361 | dependency: transitive 362 | description: 363 | name: shared_preferences_android 364 | sha256: "6478c6bbbecfe9aced34c483171e90d7c078f5883558b30ec3163cf18402c749" 365 | url: "https://pub.dev" 366 | source: hosted 367 | version: "2.1.4" 368 | shared_preferences_foundation: 369 | dependency: transitive 370 | description: 371 | name: shared_preferences_foundation 372 | sha256: e014107bb79d6d3297196f4f2d0db54b5d1f85b8ea8ff63b8e8b391a02700feb 373 | url: "https://pub.dev" 374 | source: hosted 375 | version: "2.2.2" 376 | shared_preferences_linux: 377 | dependency: transitive 378 | description: 379 | name: shared_preferences_linux 380 | sha256: "9d387433ca65717bbf1be88f4d5bb18f10508917a8fa2fb02e0fd0d7479a9afa" 381 | url: "https://pub.dev" 382 | source: hosted 383 | version: "2.2.0" 384 | shared_preferences_platform_interface: 385 | dependency: transitive 386 | description: 387 | name: shared_preferences_platform_interface 388 | sha256: fb5cf25c0235df2d0640ac1b1174f6466bd311f621574997ac59018a6664548d 389 | url: "https://pub.dev" 390 | source: hosted 391 | version: "2.2.0" 392 | shared_preferences_web: 393 | dependency: transitive 394 | description: 395 | name: shared_preferences_web 396 | sha256: "74083203a8eae241e0de4a0d597dbedab3b8fef5563f33cf3c12d7e93c655ca5" 397 | url: "https://pub.dev" 398 | source: hosted 399 | version: "2.1.0" 400 | shared_preferences_windows: 401 | dependency: transitive 402 | description: 403 | name: shared_preferences_windows 404 | sha256: "5e588e2efef56916a3b229c3bfe81e6a525665a454519ca51dbcc4236a274173" 405 | url: "https://pub.dev" 406 | source: hosted 407 | version: "2.2.0" 408 | sky_engine: 409 | dependency: transitive 410 | description: flutter 411 | source: sdk 412 | version: "0.0.99" 413 | source_span: 414 | dependency: transitive 415 | description: 416 | name: source_span 417 | sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 418 | url: "https://pub.dev" 419 | source: hosted 420 | version: "1.9.1" 421 | sqflite: 422 | dependency: transitive 423 | description: 424 | name: sqflite 425 | sha256: b4d6710e1200e96845747e37338ea8a819a12b51689a3bcf31eff0003b37a0b9 426 | url: "https://pub.dev" 427 | source: hosted 428 | version: "2.2.8+4" 429 | sqflite_common: 430 | dependency: transitive 431 | description: 432 | name: sqflite_common 433 | sha256: e77abf6ff961d69dfef41daccbb66b51e9983cdd5cb35bf30733598057401555 434 | url: "https://pub.dev" 435 | source: hosted 436 | version: "2.4.5" 437 | stack_trace: 438 | dependency: transitive 439 | description: 440 | name: stack_trace 441 | sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 442 | url: "https://pub.dev" 443 | source: hosted 444 | version: "1.11.0" 445 | stream_channel: 446 | dependency: transitive 447 | description: 448 | name: stream_channel 449 | sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" 450 | url: "https://pub.dev" 451 | source: hosted 452 | version: "2.1.1" 453 | string_scanner: 454 | dependency: transitive 455 | description: 456 | name: string_scanner 457 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 458 | url: "https://pub.dev" 459 | source: hosted 460 | version: "1.2.0" 461 | synchronized: 462 | dependency: transitive 463 | description: 464 | name: synchronized 465 | sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" 466 | url: "https://pub.dev" 467 | source: hosted 468 | version: "3.1.0" 469 | term_glyph: 470 | dependency: transitive 471 | description: 472 | name: term_glyph 473 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 474 | url: "https://pub.dev" 475 | source: hosted 476 | version: "1.2.1" 477 | test_api: 478 | dependency: transitive 479 | description: 480 | name: test_api 481 | sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb 482 | url: "https://pub.dev" 483 | source: hosted 484 | version: "0.5.1" 485 | typed_data: 486 | dependency: transitive 487 | description: 488 | name: typed_data 489 | sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c 490 | url: "https://pub.dev" 491 | source: hosted 492 | version: "1.3.2" 493 | uuid: 494 | dependency: transitive 495 | description: 496 | name: uuid 497 | sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" 498 | url: "https://pub.dev" 499 | source: hosted 500 | version: "3.0.7" 501 | vector_math: 502 | dependency: transitive 503 | description: 504 | name: vector_math 505 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 506 | url: "https://pub.dev" 507 | source: hosted 508 | version: "2.1.4" 509 | win32: 510 | dependency: transitive 511 | description: 512 | name: win32 513 | sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c" 514 | url: "https://pub.dev" 515 | source: hosted 516 | version: "4.1.4" 517 | win32_registry: 518 | dependency: transitive 519 | description: 520 | name: win32_registry 521 | sha256: "1c52f994bdccb77103a6231ad4ea331a244dbcef5d1f37d8462f713143b0bfae" 522 | url: "https://pub.dev" 523 | source: hosted 524 | version: "1.1.0" 525 | xdg_directories: 526 | dependency: transitive 527 | description: 528 | name: xdg_directories 529 | sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1 530 | url: "https://pub.dev" 531 | source: hosted 532 | version: "1.0.0" 533 | sdks: 534 | dart: ">=3.0.0-0 <4.0.0" 535 | flutter: ">=3.3.0" 536 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXCopyFilesBuildPhase section */ 19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 20 | isa = PBXCopyFilesBuildPhase; 21 | buildActionMask = 2147483647; 22 | dstPath = ""; 23 | dstSubfolderSpec = 10; 24 | files = ( 25 | ); 26 | name = "Embed Frameworks"; 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXCopyFilesBuildPhase section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 9740EEB11CF90186004384FC /* Flutter */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 65 | ); 66 | name = Flutter; 67 | sourceTree = ""; 68 | }; 69 | 97C146E51CF9000F007C117D = { 70 | isa = PBXGroup; 71 | children = ( 72 | 9740EEB11CF90186004384FC /* Flutter */, 73 | 97C146F01CF9000F007C117D /* Runner */, 74 | 97C146EF1CF9000F007C117D /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 97C146EF1CF9000F007C117D /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 97C146EE1CF9000F007C117D /* Runner.app */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 97C146F01CF9000F007C117D /* Runner */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 92 | 97C147021CF9000F007C117D /* Info.plist */, 93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 97 | ); 98 | path = Runner; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | 97C146ED1CF9000F007C117D /* Runner */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 107 | buildPhases = ( 108 | 9740EEB61CF901F6004384FC /* Run Script */, 109 | 97C146EA1CF9000F007C117D /* Sources */, 110 | 97C146EB1CF9000F007C117D /* Frameworks */, 111 | 97C146EC1CF9000F007C117D /* Resources */, 112 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 114 | ); 115 | buildRules = ( 116 | ); 117 | dependencies = ( 118 | ); 119 | name = Runner; 120 | productName = Runner; 121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 122 | productType = "com.apple.product-type.application"; 123 | }; 124 | /* End PBXNativeTarget section */ 125 | 126 | /* Begin PBXProject section */ 127 | 97C146E61CF9000F007C117D /* Project object */ = { 128 | isa = PBXProject; 129 | attributes = { 130 | LastUpgradeCheck = 1020; 131 | ORGANIZATIONNAME = ""; 132 | TargetAttributes = { 133 | 97C146ED1CF9000F007C117D = { 134 | CreatedOnToolsVersion = 7.3.1; 135 | LastSwiftMigration = 1100; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 140 | compatibilityVersion = "Xcode 9.3"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 97C146E51CF9000F007C117D; 148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 97C146ED1CF9000F007C117D /* Runner */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 97C146EC1CF9000F007C117D /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | inputPaths = ( 178 | ); 179 | name = "Thin Binary"; 180 | outputPaths = ( 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | shellPath = /bin/sh; 184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 185 | }; 186 | 9740EEB61CF901F6004384FC /* Run Script */ = { 187 | isa = PBXShellScriptBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | ); 191 | inputPaths = ( 192 | ); 193 | name = "Run Script"; 194 | outputPaths = ( 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | shellPath = /bin/sh; 198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 199 | }; 200 | /* End PBXShellScriptBuildPhase section */ 201 | 202 | /* Begin PBXSourcesBuildPhase section */ 203 | 97C146EA1CF9000F007C117D /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXSourcesBuildPhase section */ 213 | 214 | /* Begin PBXVariantGroup section */ 215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 216 | isa = PBXVariantGroup; 217 | children = ( 218 | 97C146FB1CF9000F007C117D /* Base */, 219 | ); 220 | name = Main.storyboard; 221 | sourceTree = ""; 222 | }; 223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 224 | isa = PBXVariantGroup; 225 | children = ( 226 | 97C147001CF9000F007C117D /* Base */, 227 | ); 228 | name = LaunchScreen.storyboard; 229 | sourceTree = ""; 230 | }; 231 | /* End PBXVariantGroup section */ 232 | 233 | /* Begin XCBuildConfiguration section */ 234 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | ALWAYS_SEARCH_USER_PATHS = NO; 238 | CLANG_ANALYZER_NONNULL = YES; 239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 240 | CLANG_CXX_LIBRARY = "libc++"; 241 | CLANG_ENABLE_MODULES = YES; 242 | CLANG_ENABLE_OBJC_ARC = YES; 243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_COMMA = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_EMPTY_BODY = YES; 250 | CLANG_WARN_ENUM_CONVERSION = YES; 251 | CLANG_WARN_INFINITE_RECURSION = YES; 252 | CLANG_WARN_INT_CONVERSION = YES; 253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 258 | CLANG_WARN_STRICT_PROTOTYPES = YES; 259 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 260 | CLANG_WARN_UNREACHABLE_CODE = YES; 261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 263 | COPY_PHASE_STRIP = NO; 264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 265 | ENABLE_NS_ASSERTIONS = NO; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | GCC_C_LANGUAGE_STANDARD = gnu99; 268 | GCC_NO_COMMON_BLOCKS = YES; 269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 271 | GCC_WARN_UNDECLARED_SELECTOR = YES; 272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 273 | GCC_WARN_UNUSED_FUNCTION = YES; 274 | GCC_WARN_UNUSED_VARIABLE = YES; 275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 276 | MTL_ENABLE_DEBUG_INFO = NO; 277 | SDKROOT = iphoneos; 278 | SUPPORTED_PLATFORMS = iphoneos; 279 | TARGETED_DEVICE_FAMILY = "1,2"; 280 | VALIDATE_PRODUCT = YES; 281 | }; 282 | name = Profile; 283 | }; 284 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 285 | isa = XCBuildConfiguration; 286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | CLANG_ENABLE_MODULES = YES; 290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 291 | ENABLE_BITCODE = NO; 292 | INFOPLIST_FILE = Runner/Info.plist; 293 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 294 | PRODUCT_BUNDLE_IDENTIFIER = com.mtfa.odooclient.odooCommonCodeLatest; 295 | PRODUCT_NAME = "$(TARGET_NAME)"; 296 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 297 | SWIFT_VERSION = 5.0; 298 | VERSIONING_SYSTEM = "apple-generic"; 299 | }; 300 | name = Profile; 301 | }; 302 | 97C147031CF9000F007C117D /* Debug */ = { 303 | isa = XCBuildConfiguration; 304 | buildSettings = { 305 | ALWAYS_SEARCH_USER_PATHS = NO; 306 | CLANG_ANALYZER_NONNULL = YES; 307 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 308 | CLANG_CXX_LIBRARY = "libc++"; 309 | CLANG_ENABLE_MODULES = YES; 310 | CLANG_ENABLE_OBJC_ARC = YES; 311 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 312 | CLANG_WARN_BOOL_CONVERSION = YES; 313 | CLANG_WARN_COMMA = YES; 314 | CLANG_WARN_CONSTANT_CONVERSION = YES; 315 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 316 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 317 | CLANG_WARN_EMPTY_BODY = YES; 318 | CLANG_WARN_ENUM_CONVERSION = YES; 319 | CLANG_WARN_INFINITE_RECURSION = YES; 320 | CLANG_WARN_INT_CONVERSION = YES; 321 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 322 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 323 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 324 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 325 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 326 | CLANG_WARN_STRICT_PROTOTYPES = YES; 327 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 328 | CLANG_WARN_UNREACHABLE_CODE = YES; 329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 330 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 331 | COPY_PHASE_STRIP = NO; 332 | DEBUG_INFORMATION_FORMAT = dwarf; 333 | ENABLE_STRICT_OBJC_MSGSEND = YES; 334 | ENABLE_TESTABILITY = YES; 335 | GCC_C_LANGUAGE_STANDARD = gnu99; 336 | GCC_DYNAMIC_NO_PIC = NO; 337 | GCC_NO_COMMON_BLOCKS = YES; 338 | GCC_OPTIMIZATION_LEVEL = 0; 339 | GCC_PREPROCESSOR_DEFINITIONS = ( 340 | "DEBUG=1", 341 | "$(inherited)", 342 | ); 343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 344 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 345 | GCC_WARN_UNDECLARED_SELECTOR = YES; 346 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 347 | GCC_WARN_UNUSED_FUNCTION = YES; 348 | GCC_WARN_UNUSED_VARIABLE = YES; 349 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 350 | MTL_ENABLE_DEBUG_INFO = YES; 351 | ONLY_ACTIVE_ARCH = YES; 352 | SDKROOT = iphoneos; 353 | TARGETED_DEVICE_FAMILY = "1,2"; 354 | }; 355 | name = Debug; 356 | }; 357 | 97C147041CF9000F007C117D /* Release */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | ALWAYS_SEARCH_USER_PATHS = NO; 361 | CLANG_ANALYZER_NONNULL = YES; 362 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 363 | CLANG_CXX_LIBRARY = "libc++"; 364 | CLANG_ENABLE_MODULES = YES; 365 | CLANG_ENABLE_OBJC_ARC = YES; 366 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 367 | CLANG_WARN_BOOL_CONVERSION = YES; 368 | CLANG_WARN_COMMA = YES; 369 | CLANG_WARN_CONSTANT_CONVERSION = YES; 370 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 371 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 372 | CLANG_WARN_EMPTY_BODY = YES; 373 | CLANG_WARN_ENUM_CONVERSION = YES; 374 | CLANG_WARN_INFINITE_RECURSION = YES; 375 | CLANG_WARN_INT_CONVERSION = YES; 376 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 377 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 378 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 379 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 380 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 381 | CLANG_WARN_STRICT_PROTOTYPES = YES; 382 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 383 | CLANG_WARN_UNREACHABLE_CODE = YES; 384 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 385 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 386 | COPY_PHASE_STRIP = NO; 387 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 388 | ENABLE_NS_ASSERTIONS = NO; 389 | ENABLE_STRICT_OBJC_MSGSEND = YES; 390 | GCC_C_LANGUAGE_STANDARD = gnu99; 391 | GCC_NO_COMMON_BLOCKS = YES; 392 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 393 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 394 | GCC_WARN_UNDECLARED_SELECTOR = YES; 395 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 396 | GCC_WARN_UNUSED_FUNCTION = YES; 397 | GCC_WARN_UNUSED_VARIABLE = YES; 398 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 399 | MTL_ENABLE_DEBUG_INFO = NO; 400 | SDKROOT = iphoneos; 401 | SUPPORTED_PLATFORMS = iphoneos; 402 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 403 | TARGETED_DEVICE_FAMILY = "1,2"; 404 | VALIDATE_PRODUCT = YES; 405 | }; 406 | name = Release; 407 | }; 408 | 97C147061CF9000F007C117D /* Debug */ = { 409 | isa = XCBuildConfiguration; 410 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 411 | buildSettings = { 412 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 413 | CLANG_ENABLE_MODULES = YES; 414 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 415 | ENABLE_BITCODE = NO; 416 | INFOPLIST_FILE = Runner/Info.plist; 417 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 418 | PRODUCT_BUNDLE_IDENTIFIER = com.mtfa.odooclient.odooCommonCodeLatest; 419 | PRODUCT_NAME = "$(TARGET_NAME)"; 420 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 421 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 422 | SWIFT_VERSION = 5.0; 423 | VERSIONING_SYSTEM = "apple-generic"; 424 | }; 425 | name = Debug; 426 | }; 427 | 97C147071CF9000F007C117D /* Release */ = { 428 | isa = XCBuildConfiguration; 429 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 430 | buildSettings = { 431 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 432 | CLANG_ENABLE_MODULES = YES; 433 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 434 | ENABLE_BITCODE = NO; 435 | INFOPLIST_FILE = Runner/Info.plist; 436 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 437 | PRODUCT_BUNDLE_IDENTIFIER = com.mtfa.odooclient.odooCommonCodeLatest; 438 | PRODUCT_NAME = "$(TARGET_NAME)"; 439 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 440 | SWIFT_VERSION = 5.0; 441 | VERSIONING_SYSTEM = "apple-generic"; 442 | }; 443 | name = Release; 444 | }; 445 | /* End XCBuildConfiguration section */ 446 | 447 | /* Begin XCConfigurationList section */ 448 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 449 | isa = XCConfigurationList; 450 | buildConfigurations = ( 451 | 97C147031CF9000F007C117D /* Debug */, 452 | 97C147041CF9000F007C117D /* Release */, 453 | 249021D3217E4FDB00AE95B9 /* Profile */, 454 | ); 455 | defaultConfigurationIsVisible = 0; 456 | defaultConfigurationName = Release; 457 | }; 458 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 459 | isa = XCConfigurationList; 460 | buildConfigurations = ( 461 | 97C147061CF9000F007C117D /* Debug */, 462 | 97C147071CF9000F007C117D /* Release */, 463 | 249021D4217E4FDB00AE95B9 /* Profile */, 464 | ); 465 | defaultConfigurationIsVisible = 0; 466 | defaultConfigurationName = Release; 467 | }; 468 | /* End XCConfigurationList section */ 469 | }; 470 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 471 | } 472 | --------------------------------------------------------------------------------