robert2206 8 роки тому
батько
коміт
f4a408fba9

+ 18 - 0
ionic.config.json

@@ -0,0 +1,18 @@
+{
+  "name": "OdooMobile",
+  "app_id": "",
+  "proxies": [
+  {
+    "path": "/xmlrpc",
+    "proxyUrl": "http://192.168.88.116:8069/xmlrpc/2"
+  }
+  ],
+  "gulpStartupTasks": [
+    "sass",
+    "watch"
+  ],
+  "watchPatterns": [
+    "www/**/*",
+    "!www/lib/**/*"
+  ]
+}

+ 1 - 0
scss/ionic.app.scss

@@ -17,5 +17,6 @@ $dark:                            #444 !default;
 // The path for our ionicons font files, relative to the built CSS in www/css
 $ionicons-font-path: "../lib/ionic/fonts" !default;
 
+@import 'https://fonts.googleapis.com/css?family=Harmattan';
 // Include all of Ionic
 @import "www/lib/ionic/scss/ionic";

+ 13 - 0
www/css/app.css

@@ -10,3 +10,16 @@
     margin-bottom: 10px;
     border-radius: 50px;
 }
+
+.logo {
+    width: 250px;
+    display: block;
+    margin-left: auto;
+    margin-right: auto;
+    margin-top: 100px;
+    margin-bottom: 15px;
+}
+
+.logo-footer {
+    font-size: 10pt;
+}

+ 14 - 4
www/index.html

@@ -9,17 +9,27 @@
     <link href="css/ionic.app.min.css" rel="stylesheet">
     <link href="css/app.css" rel="stylesheet">
 
+    <!-- Libs -->
     <script src="lib/ionic/js/ionic.bundle.js"></script>
     <script src="lib/ngCordova/dist/ng-cordova.min.js"></script>
     <script src="cordova.js"></script>
+    <!-- Main -->
     <script src="js/app.js"></script>
     <!-- Controllers -->
-    <script src="js/controllers.js"></script>
-    <script src="js/factories.js"></script>
+    <script src="js/controllers/app.controller.js"></script>
+    <script src="js/controllers/main.controller.js"></script>
+    <script src="js/controllers/sale.controller.js"></script>
+    <script src="js/controllers/customer.controller.js"></script>
+    <script src="js/controllers/configuration.controller.js"></script>
+    <!-- Factories -->
+    <script src="js/factories/utils.factory.js"></script>
+    <script src="js/factories/storage.factory.js"></script>
+    <script src="js/factories/odoo.factory.js"></script>
+    <script src="js/factories/sync.factory.js"></script>
+    <!-- 3rd Party -->
     <script src="lib/angular-xmlrpc/xmlrpc.js"></script>
   </head>
   <body ng-app="odoo">
-      <ion-nav-view animation="slide-left-right">
-      </ion-nav-view>
+      <ion-nav-view animation="slide-left-right"></ion-nav-view>
   </body>
 </html>

+ 12 - 2
www/js/app.js

@@ -1,4 +1,14 @@
-angular.module('odoo', ['ionic', 'odoo.controllers'])
+angular.module(
+    'odoo',
+    [
+        'ionic',
+        'odoo.app.controller',
+        'odoo.main.controller',
+        'odoo.sale.controller',
+        'odoo.customer.controller',
+        'odoo.configuration.controller',
+    ]
+)
 
 .directive('onErrorSrc', function() {
     return {
@@ -90,7 +100,7 @@ angular.module('odoo', ['ionic', 'odoo.controllers'])
             views: {
                 'content': {
                     templateUrl: 'templates/sales.html',
-                    controller: 'VentasController'
+                    controller: 'SaleController'
                 }
             }
         })

+ 5 - 0
www/js/controllers/app.controller.js

@@ -0,0 +1,5 @@
+angular.module('odoo.app.controller', [])
+
+.controller('AppController', function ($scope) {
+    console.log('app controller');
+});

+ 56 - 0
www/js/controllers/configuration.controller.js

@@ -0,0 +1,56 @@
+angular.module(
+    'odoo.configuration.controller',
+    [
+        'odoo.interoperability.factory',
+        'odoo.storage.factory'
+    ]
+)
+
+.controller('ConfigurationController', function($scope, $state, $ionicLoading, $ionicPopup, odoo, storage) {
+    $scope.config = { host: '192.168.88.116', port: 8069, database: 'odoo', username: 'admin', password: 'admin' }
+
+    // Apply configuration for app
+    $scope.configure = function () {
+        $ionicLoading.show();
+
+        storage.count('user', function (total) {
+            if (total == 0) {
+                odoo.auth($scope.config, function (user) {
+                    storage.saveUser(
+                        [
+                            user.id,
+                            $scope.config.host,
+                            $scope.config.port,
+                            $scope.config.database,
+                            user.username,
+                            user.password
+                        ], function (newId) {
+
+                            $ionicLoading.hide();
+                            $state.go('app.main');
+                            console.log(newId);
+                    }, function (error) {
+
+                        $ionicLoading.hide();
+                        console.log(error);
+                    });
+                }, function (error) {
+                    $ionicLoading.hide();
+
+                    var message = 'Configuración no válida';
+                    if (angular.isObject(error)) {
+                        message = 'No se pudo establecer una llamada al servidor';
+                    }
+
+                    $ionicPopup.alert({ title: 'Ha fallado el inicio de sesión', template: message });
+                });
+            } else {
+                $ionicLoading.hide();
+                $state.go('app.main');
+            }
+        }, function (error) {
+            $ionicLoading.hide();
+            console.log(error);
+        });
+    }
+});

+ 22 - 53
www/js/controllers.js → www/js/controllers/customer.controller.js

@@ -1,18 +1,26 @@
-angular.module('odoo.controllers', ['odoo.factories', 'ngCordova'])
+angular.module(
+    'odoo.customer.controller',
+    [
+        'odoo.interoperability.factory',
+        'odoo.storage.factory',
+        'ngCordova'
+    ]
+)
+
+.controller('CustomersController', function (
+    $scope,
+    $log,
+    $ionicLoading,
+    $ionicModal,
+    $ionicActionSheet,
+    $ionicPopup,
+    $cordovaContacts,
+    $cordovaCamera,
+    sync,
+    odoo,
+    storage
+) {
 
-.controller('AppController', function ($scope) {
-    console.log("I'm AppController");
-})
-
-.controller('MainController', function ($scope) {
-    console.log("I'm MainController");
-})
-
-.controller('VentasController', function ($scope) {
-
-})
-
-.controller('CustomersController', function ($scope, $log, $ionicLoading, $ionicModal, $ionicActionSheet, $ionicPopup, $cordovaContacts, $cordovaCamera, sync, odoo, storage) {
     // Objects
     $scope.customer = {};
     $scope.customers = [];
@@ -242,43 +250,4 @@ angular.module('odoo.controllers', ['odoo.factories', 'ngCordova'])
             $log.error(JSON.stringify(err));
         });
     }
-})
-
-.controller('ConfigurationController', function($scope, $state, $ionicLoading, $ionicPopup, odoo, storage) {
-    $scope.config = { host: '192.168.88.116', port: 8069, database: 'odoo', username: 'admin', password: 'admin' }
-
-    // Apply configuration for app
-    $scope.configure = function () {
-        $ionicLoading.show();
-
-        storage.count('user', function (total) {
-            if (total == 0) {
-                odoo.auth($scope.config, function (user) {
-                    storage.saveUser([user.id, $scope.config.host, $scope.config.port, $scope.config.database, user.username, user.password], function (newId) {
-                        $ionicLoading.hide();
-                        $state.go('app.main');
-                        console.log(newId);
-                    }, function (error) {
-                        $ionicLoading.hide();
-                        console.log(error);
-                    });
-                }, function (error) {
-                    $ionicLoading.hide();
-
-                    var message = 'Configuración no válida';
-                    if (angular.isObject(error)) {
-                        message = 'No se pudo establecer una llamada al servidor';
-                    }
-
-                    $ionicPopup.alert({ title: 'Ha fallado el inicio de sesión', template: message });
-                });
-            } else {
-                $ionicLoading.hide();
-                $state.go('app.main');
-            }
-        }, function (error) {
-            $ionicLoading.hide();
-            console.log(error);
-        });
-    }
 });

+ 5 - 0
www/js/controllers/main.controller.js

@@ -0,0 +1,5 @@
+angular.module('odoo.main.controller', [])
+
+.controller('MainController', function ($scope) {
+    console.log('main controller');
+});

+ 5 - 0
www/js/controllers/sale.controller.js

@@ -0,0 +1,5 @@
+angular.module('odoo.sale.controller', [])
+
+.controller('SaleController', function ($scope) {
+    console.log('sale controller');
+});

+ 0 - 338
www/js/factories.js

@@ -1,338 +0,0 @@
-angular.module('odoo.factories', ['xml-rpc'])
-
-.factory('util', function () {
-    return {
-        asyncLoop : function (iterations, func, callback) {
-            var index = 0;
-            var done = false;
-            var loop = {
-                next: function  () {
-                    if (done) {
-                        return;
-                    }
-
-                    if (index < iterations) {
-                        index++;
-                        func(loop);
-
-                    } else {
-                        done = true;
-                        callback();
-                    }
-                },
-
-                iteration: function() {
-                    return index - 1;
-                },
-
-                break: function() {
-                    done = true;
-                    callback();
-                }
-            };
-
-            loop.next();
-            return loop;
-        }
-    }
-})
-
-.factory('odoo', function (xmlrpc, methodCallManager) {
-    return {
-        auth: function (config, success, error) {
-            xmlrpc.callMethod(methodCallManager.call('authenticate', config), [config.database, config.username, config.password, {}]).then(function(response) {
-                if (!response || response['faultCode']) {
-                    error(response);
-                    return;
-                }
-
-                success({ id: response, username: config.username, password: config.password });
-            }, function (xmlrpcError) {
-                error(xmlrpcError);
-            });
-        },
-        read: function (model, domain, config, success, error) {
-            xmlrpc.callMethod(methodCallManager.call('execute_kw', config), [config.database, config.remote_id, config.password, model, 'search_read', [domain]]).then(function (response) {
-                if (!response || response['faultCode']) {
-                    error(response);
-                    return;
-                }
-
-                success(response);
-            }, function (xmlrpcError) {
-                error(xmlrpcError);
-            });
-        },
-        create: function (model, data, config, success, error) {
-            xmlrpc.callMethod(methodCallManager.call('execute_kw', config), [config.database, config.remote_id, config.password, model, 'create', [data]]).then(function (response) {
-                if (!response || response['faultCode']) {
-                    error(response);
-                    return;
-                }
-
-                success(response);
-            }, function (xmlrpcError) {
-                error(xmlrpcError);
-            });
-        },
-        write: function (model, id, data, config, success, error) {
-            xmlrpc.callMethod(methodCallManager.call('execute_kw', config), [config.database, config.remote_id, config.password, model, 'write', [[id], data]]).then(function (response) {
-                if (!response || response['faultCode']) {
-                    error(response);
-                    return;
-                }
-
-                success(response);
-            }, function (xmlrpcError) {
-                error(xmlrpcError);
-            });
-        },
-        unlink: function (model, id, config, success, error) {
-            xmlrpc.callMethod(methodCallManager.call('execute_kw', config), [config.database, config.remote_id, config.password, model, 'unlink', [[id]]]).then(function (response) {
-                if (!response || response['faultCode']) {
-                    error(response);
-                    return;
-                }
-
-                success(response);
-            }, function (xmlrpcError) {
-                error(xmlrpcError);
-            });
-        }
-    }
-})
-
-.factory('methodCallManager', function(xmlrpc) {
-    return {
-        call: function(methodName, configuration) {
-            var hostName = configuration.host + ':' + configuration.port;
-
-            if(!hostName.startsWith('http://')) {
-                hostName = 'http://' + hostName;
-            }
-
-            if(methodName == 'authenticate') {
-                xmlrpc.config({ hostName: hostName, pathName: '/xmlrpc/2/common' });
-            } else {
-                xmlrpc.config({ hostName: hostName, pathName: '/xmlrpc/2/object' });
-            }
-
-            return methodName;
-        }
-    }
-})
-
-.factory('sync', function (storage, odoo, util) {
-    return {
-        syncCustomers: function (success, error) {
-            // Get current user saved on mobile
-            storage.get('user', function (users) {
-                if (users.length == 1) {
-                    var userConfig = users.item(0);
-
-                    // 1. Transfer all new data from mobile to server
-                    storage.getByConstraint('partner', 'remote_id = 0 AND customer = 1', function(newPartners) {
-                        util.asyncLoop(newPartners.length, function (loop) {
-                            var data = newPartners.item(loop.iteration());
-
-                            // Avoid odoo server warning message
-                            delete data.id;
-                            delete data.remote_id;
-                            delete data.modified;
-                            delete data.modifiedDate;
-
-                            odoo.create('res.partner', data, userConfig, function (response) {
-                                loop.next();
-                            }, function (odooCreateError) {
-                                loop.break();
-                            });
-
-                        // End loop
-                        }, function() {
-                            // 2. Transfer all modified data from mobile to server
-                            storage.getByConstraint('partner', 'remote_id != 0 AND customer = 1 AND modified = 1', function (modifiedPartners) {
-                                util.asyncLoop(modifiedPartners.length, function (loop) {
-                                    var localData = modifiedPartners.item(loop.iteration());
-
-                                    odoo.read('res.partner', [['id', '=', localData.remote_id]], userConfig, function (response) {
-                                        if (response.length == 1) {
-                                            var remoteData = response[0];
-
-                                            var remoteModifiedDate = new Date(remoteData.__last_update);
-                                            var localModifiedDate = new Date(localData.modifiedDate);
-
-                                            if (localModifiedDate > remoteModifiedDate) {
-                                                var id = localData.remote_id;
-
-                                                // Avoid odoo server warning message
-                                                delete localData.id;
-                                                delete localData.remote_id;
-                                                delete localData.modified;
-                                                delete localData.modifiedDate;
-
-                                                odoo.write('res.partner', id, localData, userConfig, function (response) {
-                                                    loop.next();
-                                                }, function (odooWriteError) {
-                                                    console.error(odooWriteError);
-                                                    loop.next();
-                                                });
-                                            } else {
-                                                loop.next();
-                                            }
-                                        } else {
-                                            loop.next();
-                                        }
-                                    }, function(odooReadError) {
-                                        console.error(odooReadError);
-                                        loop.next();
-                                    });
-
-                                // End loop
-                                }, function () {
-                                    // 3. Delete server data from mobile
-                                    storage.getByConstraint('partner', 'remote_id != 0 AND customer = 1 AND modified = 2', function (deletedPartners) {
-                                        util.asyncLoop(deletedPartners.length, function (loop) {
-                                            var id = deletedPartners.item(loop.iteration()).remote_id;
-
-                                            odoo.unlink('res.partner', id, userConfig, function (response) {
-                                                loop.next();
-                                            }, function (odooUnlinkError) {
-                                                console.error(odooUnlinkError);
-                                                loop.next();
-                                            });
-
-                                        // End loop
-                                        }, function () {
-                                            // 4. Download updated data from server to mobile
-                                            odoo.read('res.partner', [['customer', '=', true]], userConfig, function (updatedPartners) {
-                                                storage.deleteAllCustomers(function () {
-                                                    util.asyncLoop(updatedPartners.length, function (loop) {
-                                                        var data = updatedPartners[loop.iteration()];
-
-                                                        // Set id for save on local database
-                                                        data.remote_id = data.id;
-                                                        delete data.id;
-
-                                                        storage.saveCustomer(data, function (customerId) {
-                                                            loop.next();
-                                                        } ,function (saveCustomerError) {
-                                                            console.error(saveCustomerError);
-                                                            loop.next();
-                                                        });
-                                                    }, function () {
-                                                        success(updatedPartners);
-                                                    });
-                                                }, function (deleteAllCustomersError) {
-                                                    error(deleteAllCustomersError);
-                                                });
-                                            }, function (odooReadError) {
-                                                error(odooReadError);
-                                            });
-                                        });
-                                    }, function (getDeletedPartnersError) {
-                                        error(getDeletedPartnersError);
-                                    });
-                                });
-                            }, function (getModifiedPartnersError) {
-                                error(getModifiedPartnersError);
-                            });
-                        });
-                    }, function (partnerGetByConstraintError) {
-                        error(partnerGetByConstraintError);
-                    });
-                }
-            }, function(userGetError) {
-                error(userGetError);
-            });
-        }
-    }
-})
-
-.factory('storage', function () {
-    return {
-        // Customer
-        saveCustomer(customer, success, error) {
-            var sql = '';
-
-            if (customer.id) {
-                sql = `UPDATE partner SET remote_id = ${ customer.remote_id ? customer.remote_id : 0  }, modified = 1, modifiedDate = CURRENT_TIMESTAMP, name = ${ customer.name ? '"' + customer.name + '"' : null }, city = ${ customer.city ? '"' + customer.city + '"' : null }, mobile = ${ customer.mobile ? '"' + customer.mobile + '"' : null }, phone = ${ customer.phone ? '"' + customer.phone + '"' : null }, fax = ${ customer.fax ? '"' + customer.fax + '"' : null }, email = ${ customer.email ? '"' + customer.email + '"' : null }, street = ${ customer.street ? '"' + customer.street + '"' : null }, street2 = ${ customer.street2 ? '"' + customer.street2 + '"' : null }, image_medium = ${ customer.image_medium ? '"' + customer.image_medium + '"' : null }, image_small = ${ customer.image_small ? '"' + customer.image_small + '"' : null }, comment = ${ customer.comment ? '"' + customer.comment + '"' : null }, customer = ${ customer.customer ? customer.customer : 1 }, employee = ${ customer.employee ? customer.employee : 0 }, is_company = ${ customer.is_company ? customer.is_company : 0 }, debit = ${ customer.debit ? customer.debit : 0 }, debit_limit = ${ customer.debit_limit ? customer.debit_limit : 0 }, opportunity_count = ${ customer.opportunity_count ? customer.opportunity_count : 0 }, contracts_count = ${ customer.contracts_count ? customer.contracts_count : 0 }, journal_item_count = ${ customer.journal_item_count ? customer.journal_item_count : 0 }, meeting_count = ${ customer.meeting_count ? customer.meeting_count : 0 }, phonecall_count = ${ customer.phonecall_count ? customer.phonecall_count : 0 }, sale_order_count = ${ customer.sale_order_count ? customer.sale_order_count : 0 }, total_invoiced = ${ customer.total_invoiced ? customer.total_invoiced : 0 } WHERE id = ${ customer.id }`;
-            } else {
-                sql = `INSERT INTO partner(remote_id, name, city, mobile, phone, fax, email, street, street2, image_medium, image_small, comment, customer, employee, is_company, debit, debit_limit, opportunity_count, contracts_count, journal_item_count, meeting_count, phonecall_count, sale_order_count, total_invoiced) VALUES (${ customer.remote_id ? customer.remote_id : 0 }, ${ customer.name ? '"' + customer.name + '"' : null }, ${ customer.city ? '"' + customer.city + '"' : null }, ${ customer.mobile ? '"' + customer.mobile + '"' : null }, ${ customer.phone ? '"' + customer.phone + '"' : null }, ${ customer.fax ? '"' + customer.fax + '"' : null }, ${ customer.email ? '"' + customer.email + '"' : null }, ${ customer.street ? '"' + customer.street + '"' : null }, ${ customer.street2 ? '"' + customer.street2 + '"' : null }, ${ customer.image_medium ? '"' + customer.image_medium + '"' : null }, ${ customer.image_small ? '"' + customer.image_small + '"' : null }, ${ customer.comment ? '"' + customer.comment + '"' : null }, 1, 0, 0, ${ customer.debit ? customer.debit : 0 }, ${ customer.debit_limit ? customer.debit_limit : 0 }, ${ customer.opportunity_count ? customer.opportunity_count : 0 }, ${ customer.contracts_count ? customer.contracts_count : 0 }, ${ customer.journal_item_count ? customer.journal_item_count : 0 }, ${ customer.meeting_count ? customer.meeting_count : 0 }, ${ customer.phonecall_count ? customer.phonecall_count : 0 }, ${ customer.sale_order_count ? customer.sale_order_count : 0 }, ${ customer.total_invoiced ? customer.total_invoiced : 0 })`;
-            }
-
-            db.executeSql(sql, [], function(result) {
-                success(sql.startsWith('INSERT') ? result.insertId : customer.id);
-            }, function(err) {
-                error(err);
-            });
-        },
-        deleteCustomer(customer, success, error) {
-            if (!customer.id) {
-                error('Customer cannot delete without provide an id');
-            }
-
-            var sql = '';
-
-            if (customer.remote_id) {
-                sql = `UPDATE partner SET modified = 2 WHERE id = ${ customer.id }`;
-            } else {
-                sql = `DELETE FROM partner WHERE id = ${ customer.id }`;
-            }
-
-            console.log(sql);
-
-            db.executeSql(sql, [], function(result) {
-                success(result.rowsAffected);
-            }, function(err) {
-                error(err);
-            });
-        },
-        deleteAllCustomers(success, error) {
-            var sql = 'DELETE FROM partner WHERE customer = 1';
-
-            db.executeSql(sql, [], function(result) {
-                success(result.rowsAffected);
-            }, function(err) {
-                error(err);
-            });
-        },
-        // Users
-        saveUser: function(data, success, error) {
-            var sql = 'INSERT INTO user(remote_id, host, port, database, username, password) VALUES(?, ?, ?, ?, ?, ?)';
-
-            db.executeSql(sql, data, function (result) {
-                success(result.insertId);
-            }, function (err) {
-                error(err);
-            });
-        },
-        // Utils
-        get: function(tableName, success, error) {
-            var sql = 'SELECT * FROM ' + tableName;
-
-            db.executeSql(sql, [], function(result) {
-                success(result.rows);
-            }, function(err) {
-                error(err);
-            });
-        },
-        getByConstraint: function(tableName, constraint, success, error) {
-            var sql = 'SELECT * FROM ' + tableName + ' WHERE ' + constraint;
-
-            db.executeSql(sql, [], function(result) {
-                success(result.rows);
-            }, function(err) {
-                error(err);
-            });
-        },
-        count: function(tableName, success, error) {
-            var sql = 'SELECT COUNT(*) AS total FROM ' + tableName;
-
-            db.executeSql(sql, [], function(result) {
-                success(result.rows.item(0).total);
-            }, function(err) {
-                error(err);
-            });
-        }
-    }
-});

+ 86 - 0
www/js/factories/odoo.factory.js

@@ -0,0 +1,86 @@
+angular.module('odoo.interoperability.factory', ['xml-rpc'])
+
+.factory('odoo', function (xmlrpc, methodCallManager) {
+    return {
+        auth: function (config, success, error) {
+            xmlrpc.callMethod(methodCallManager.call('authenticate', config), [config.database, config.username, config.password, {}]).then(function(response) {
+                if (!response || response['faultCode']) {
+                    error(response);
+                    return;
+                }
+
+                success({ id: response, username: config.username, password: config.password });
+            }, function (xmlrpcError) {
+                error(xmlrpcError);
+            });
+        },
+        read: function (model, domain, config, success, error) {
+            xmlrpc.callMethod(methodCallManager.call('execute_kw', config), [config.database, config.remote_id, config.password, model, 'search_read', [domain]]).then(function (response) {
+                if (!response || response['faultCode']) {
+                    error(response);
+                    return;
+                }
+
+                success(response);
+            }, function (xmlrpcError) {
+                error(xmlrpcError);
+            });
+        },
+        create: function (model, data, config, success, error) {
+            xmlrpc.callMethod(methodCallManager.call('execute_kw', config), [config.database, config.remote_id, config.password, model, 'create', [data]]).then(function (response) {
+                if (!response || response['faultCode']) {
+                    error(response);
+                    return;
+                }
+
+                success(response);
+            }, function (xmlrpcError) {
+                error(xmlrpcError);
+            });
+        },
+        write: function (model, id, data, config, success, error) {
+            xmlrpc.callMethod(methodCallManager.call('execute_kw', config), [config.database, config.remote_id, config.password, model, 'write', [[id], data]]).then(function (response) {
+                if (!response || response['faultCode']) {
+                    error(response);
+                    return;
+                }
+
+                success(response);
+            }, function (xmlrpcError) {
+                error(xmlrpcError);
+            });
+        },
+        unlink: function (model, id, config, success, error) {
+            xmlrpc.callMethod(methodCallManager.call('execute_kw', config), [config.database, config.remote_id, config.password, model, 'unlink', [[id]]]).then(function (response) {
+                if (!response || response['faultCode']) {
+                    error(response);
+                    return;
+                }
+
+                success(response);
+            }, function (xmlrpcError) {
+                error(xmlrpcError);
+            });
+        }
+    }
+})
+
+.factory('methodCallManager', function(xmlrpc) {
+    return {
+        call: function(methodName, configuration) {
+            var hostName = configuration.host + ':' + configuration.port;
+
+            if(!hostName.startsWith('http://')) {
+                hostName = 'http://' + hostName;
+            }
+
+            if(methodName == 'authenticate') {
+                xmlrpc.config({ hostName: hostName, pathName: '/xmlrpc/2/common' });
+            } else {
+                xmlrpc.config({ hostName: hostName, pathName: '/xmlrpc/2/object' });
+            }
+
+            return methodName;
+        }
+    }
+});

+ 90 - 0
www/js/factories/storage.factory.js

@@ -0,0 +1,90 @@
+angular.module('odoo.storage.factory', [])
+
+.factory('storage', function () {
+    return {
+        // Customer
+        saveCustomer(customer, success, error) {
+            var sql = '';
+
+            if (customer.id) {
+                sql = `UPDATE partner SET remote_id = ${ customer.remote_id ? customer.remote_id : 0  }, modified = 1, modifiedDate = CURRENT_TIMESTAMP, name = ${ customer.name ? '"' + customer.name + '"' : null }, city = ${ customer.city ? '"' + customer.city + '"' : null }, mobile = ${ customer.mobile ? '"' + customer.mobile + '"' : null }, phone = ${ customer.phone ? '"' + customer.phone + '"' : null }, fax = ${ customer.fax ? '"' + customer.fax + '"' : null }, email = ${ customer.email ? '"' + customer.email + '"' : null }, street = ${ customer.street ? '"' + customer.street + '"' : null }, street2 = ${ customer.street2 ? '"' + customer.street2 + '"' : null }, image_medium = ${ customer.image_medium ? '"' + customer.image_medium + '"' : null }, image_small = ${ customer.image_small ? '"' + customer.image_small + '"' : null }, comment = ${ customer.comment ? '"' + customer.comment + '"' : null }, customer = ${ customer.customer ? customer.customer : 1 }, employee = ${ customer.employee ? customer.employee : 0 }, is_company = ${ customer.is_company ? customer.is_company : 0 }, debit = ${ customer.debit ? customer.debit : 0 }, debit_limit = ${ customer.debit_limit ? customer.debit_limit : 0 }, opportunity_count = ${ customer.opportunity_count ? customer.opportunity_count : 0 }, contracts_count = ${ customer.contracts_count ? customer.contracts_count : 0 }, journal_item_count = ${ customer.journal_item_count ? customer.journal_item_count : 0 }, meeting_count = ${ customer.meeting_count ? customer.meeting_count : 0 }, phonecall_count = ${ customer.phonecall_count ? customer.phonecall_count : 0 }, sale_order_count = ${ customer.sale_order_count ? customer.sale_order_count : 0 }, total_invoiced = ${ customer.total_invoiced ? customer.total_invoiced : 0 } WHERE id = ${ customer.id }`;
+            } else {
+                sql = `INSERT INTO partner(remote_id, name, city, mobile, phone, fax, email, street, street2, image_medium, image_small, comment, customer, employee, is_company, debit, debit_limit, opportunity_count, contracts_count, journal_item_count, meeting_count, phonecall_count, sale_order_count, total_invoiced) VALUES (${ customer.remote_id ? customer.remote_id : 0 }, ${ customer.name ? '"' + customer.name + '"' : null }, ${ customer.city ? '"' + customer.city + '"' : null }, ${ customer.mobile ? '"' + customer.mobile + '"' : null }, ${ customer.phone ? '"' + customer.phone + '"' : null }, ${ customer.fax ? '"' + customer.fax + '"' : null }, ${ customer.email ? '"' + customer.email + '"' : null }, ${ customer.street ? '"' + customer.street + '"' : null }, ${ customer.street2 ? '"' + customer.street2 + '"' : null }, ${ customer.image_medium ? '"' + customer.image_medium + '"' : null }, ${ customer.image_small ? '"' + customer.image_small + '"' : null }, ${ customer.comment ? '"' + customer.comment + '"' : null }, 1, 0, 0, ${ customer.debit ? customer.debit : 0 }, ${ customer.debit_limit ? customer.debit_limit : 0 }, ${ customer.opportunity_count ? customer.opportunity_count : 0 }, ${ customer.contracts_count ? customer.contracts_count : 0 }, ${ customer.journal_item_count ? customer.journal_item_count : 0 }, ${ customer.meeting_count ? customer.meeting_count : 0 }, ${ customer.phonecall_count ? customer.phonecall_count : 0 }, ${ customer.sale_order_count ? customer.sale_order_count : 0 }, ${ customer.total_invoiced ? customer.total_invoiced : 0 })`;
+            }
+
+            db.executeSql(sql, [], function(result) {
+                success(sql.startsWith('INSERT') ? result.insertId : customer.id);
+            }, function(err) {
+                error(err);
+            });
+        },
+        deleteCustomer(customer, success, error) {
+            if (!customer.id) {
+                error('Customer cannot delete without provide an id');
+            }
+
+            var sql = '';
+
+            if (customer.remote_id) {
+                sql = `UPDATE partner SET modified = 2 WHERE id = ${ customer.id }`;
+            } else {
+                sql = `DELETE FROM partner WHERE id = ${ customer.id }`;
+            }
+
+            console.log(sql);
+
+            db.executeSql(sql, [], function(result) {
+                success(result.rowsAffected);
+            }, function(err) {
+                error(err);
+            });
+        },
+        deleteAllCustomers(success, error) {
+            var sql = 'DELETE FROM partner WHERE customer = 1';
+
+            db.executeSql(sql, [], function(result) {
+                success(result.rowsAffected);
+            }, function(err) {
+                error(err);
+            });
+        },
+        // Users
+        saveUser: function(data, success, error) {
+            var sql = 'INSERT INTO user(remote_id, host, port, database, username, password) VALUES(?, ?, ?, ?, ?, ?)';
+
+            db.executeSql(sql, data, function (result) {
+                success(result.insertId);
+            }, function (err) {
+                error(err);
+            });
+        },
+        // Utils
+        get: function(tableName, success, error) {
+            var sql = 'SELECT * FROM ' + tableName;
+
+            db.executeSql(sql, [], function(result) {
+                success(result.rows);
+            }, function(err) {
+                error(err);
+            });
+        },
+        getByConstraint: function(tableName, constraint, success, error) {
+            var sql = 'SELECT * FROM ' + tableName + ' WHERE ' + constraint;
+
+            db.executeSql(sql, [], function(result) {
+                success(result.rows);
+            }, function(err) {
+                error(err);
+            });
+        },
+        count: function(tableName, success, error) {
+            var sql = 'SELECT COUNT(*) AS total FROM ' + tableName;
+
+            db.executeSql(sql, [], function(result) {
+                success(result.rows.item(0).total);
+            }, function(err) {
+                error(err);
+            });
+        }
+    }
+});

+ 134 - 0
www/js/factories/sync.factory.js

@@ -0,0 +1,134 @@
+angular.module(
+    'odoo.sync.factory',
+    [
+        'odoo.utils.factory',
+        'odoo.interoperability.factory',
+        'odoo.storage.factory'
+    ]
+)
+
+.factory('sync', function (storage, odoo, async) {
+    return {
+        syncCustomers: function (success, error) {
+            // Get current user saved on mobile
+            storage.get('user', function (users) {
+                if (users.length == 1) {
+                    var userConfig = users.item(0);
+
+                    // 1. Transfer all new data from mobile to server
+                    storage.getByConstraint('partner', 'remote_id = 0 AND customer = 1', function(newPartners) {
+                        async.loop(newPartners.length, function (loop) {
+                            var data = newPartners.item(loop.iteration());
+
+                            // Avoid odoo server warning message
+                            delete data.id;
+                            delete data.remote_id;
+                            delete data.modified;
+                            delete data.modifiedDate;
+
+                            odoo.create('res.partner', data, userConfig, function (response) {
+                                loop.next();
+                            }, function (odooCreateError) {
+                                loop.break();
+                            });
+
+                        // End loop
+                        }, function() {
+                            // 2. Transfer all modified data from mobile to server
+                            storage.getByConstraint('partner', 'remote_id != 0 AND customer = 1 AND modified = 1', function (modifiedPartners) {
+                                async.loop(modifiedPartners.length, function (loop) {
+                                    var localData = modifiedPartners.item(loop.iteration());
+
+                                    odoo.read('res.partner', [['id', '=', localData.remote_id]], userConfig, function (response) {
+                                        if (response.length == 1) {
+                                            var remoteData = response[0];
+
+                                            var remoteModifiedDate = new Date(remoteData.__last_update);
+                                            var localModifiedDate = new Date(localData.modifiedDate);
+
+                                            if (localModifiedDate > remoteModifiedDate) {
+                                                var id = localData.remote_id;
+
+                                                // Avoid odoo server warning message
+                                                delete localData.id;
+                                                delete localData.remote_id;
+                                                delete localData.modified;
+                                                delete localData.modifiedDate;
+
+                                                odoo.write('res.partner', id, localData, userConfig, function (response) {
+                                                    loop.next();
+                                                }, function (odooWriteError) {
+                                                    console.error(odooWriteError);
+                                                    loop.next();
+                                                });
+                                            } else {
+                                                loop.next();
+                                            }
+                                        } else {
+                                            loop.next();
+                                        }
+                                    }, function(odooReadError) {
+                                        console.error(odooReadError);
+                                        loop.next();
+                                    });
+
+                                // End loop
+                                }, function () {
+                                    // 3. Delete server data from mobile
+                                    storage.getByConstraint('partner', 'remote_id != 0 AND customer = 1 AND modified = 2', function (deletedPartners) {
+                                        async.loop(deletedPartners.length, function (loop) {
+                                            var id = deletedPartners.item(loop.iteration()).remote_id;
+
+                                            odoo.unlink('res.partner', id, userConfig, function (response) {
+                                                loop.next();
+                                            }, function (odooUnlinkError) {
+                                                console.error(odooUnlinkError);
+                                                loop.next();
+                                            });
+
+                                        // End loop
+                                        }, function () {
+                                            // 4. Download updated data from server to mobile
+                                            odoo.read('res.partner', [['customer', '=', true]], userConfig, function (updatedPartners) {
+                                                storage.deleteAllCustomers(function () {
+                                                    async.loop(updatedPartners.length, function (loop) {
+                                                        var data = updatedPartners[loop.iteration()];
+
+                                                        // Set id for save on local database
+                                                        data.remote_id = data.id;
+                                                        delete data.id;
+
+                                                        storage.saveCustomer(data, function (customerId) {
+                                                            loop.next();
+                                                        } ,function (saveCustomerError) {
+                                                            console.error(saveCustomerError);
+                                                            loop.next();
+                                                        });
+                                                    }, function () {
+                                                        success(updatedPartners);
+                                                    });
+                                                }, function (deleteAllCustomersError) {
+                                                    error(deleteAllCustomersError);
+                                                });
+                                            }, function (odooReadError) {
+                                                error(odooReadError);
+                                            });
+                                        });
+                                    }, function (getDeletedPartnersError) {
+                                        error(getDeletedPartnersError);
+                                    });
+                                });
+                            }, function (getModifiedPartnersError) {
+                                error(getModifiedPartnersError);
+                            });
+                        });
+                    }, function (partnerGetByConstraintError) {
+                        error(partnerGetByConstraintError);
+                    });
+                }
+            }, function(userGetError) {
+                error(userGetError);
+            });
+        }
+    }
+});

+ 38 - 0
www/js/factories/utils.factory.js

@@ -0,0 +1,38 @@
+angular.module('odoo.utils.factory', [])
+
+.factory('async', function () {
+    return {
+        loop: function (iterations, func, callback) {
+            var index = 0;
+            var done = false;
+            var loop = {
+                next: function  () {
+                    if (done) {
+                        return;
+                    }
+
+                    if (index < iterations) {
+                        index++;
+                        func(loop);
+
+                    } else {
+                        done = true;
+                        callback();
+                    }
+                },
+
+                iteration: function() {
+                    return index - 1;
+                },
+
+                break: function() {
+                    done = true;
+                    callback();
+                }
+            };
+
+            loop.next();
+            return loop;
+        }
+    }
+});

Різницю між файлами не показано, бо вона завелика
+ 0 - 0
www/templates/main.html


Деякі файли не було показано, через те що забагато файлів було змінено