網頁

2014年11月4日 星期二

asp.net MVC 多國語系設定



參考文件

ASP.NET MVC 讓 jQuery Validation Plugin 動態切換顯示訊息語系

ASP.NET MVC And Localization

ASP.NET Boilerplate Localization

ASP.NET MVC 你一定要知道怎麼創立HTML Helper

Attributes Tutorial

Localization in ASP.NET MVC 4 – Upgraded

asp.net mvc multilanguage urls/routing  =>要客製一個 controller而且所有新建的controller都要繼承它

ASP.NET MVC Localization - Routing  => controller不用繼承客制的 controller (目前我使用的)

目前我參考的這一個算是蠻好設定的而且有範例碼在 GitHub,自己也有學到新東西

比如 RouteCollectionExtensions,建立一個靜態的類別,在 RouteConfig就可以使用它的方法

public static class RouteCollectionExtensions,而在作語系切換時只要將 cookie locale的值設定為指定語系即可

ASP.NET MVC + ANGULARJS SPA + LOCALIZATION


ASP.NET MVC With AngularJS

如果有使用 angularjs 並且將網頁設定成 SPA方式的話,我使用的方式還要再作修改,要不然angularjs route碰到下列情況就會有問題

 .when('/routeTwo/:donuts', {
            templateUrl: function(params) { return '/routesDemo/two?donuts=' + params.donuts; }
        })


因為在原作者再作 redirect new url時並沒有把 request params (querystring)的參數帶入,所以要在 RedirectHandler的 ProcessRequest內再把參數帶入

 public void ProcessRequest(HttpContext context)
 {
            NameValueCollection queryParameters = context.Request.QueryString;
            string qTring = string.Empty;

            if (queryParameters.Count > 0)
            {
                qTring = "?" + queryParameters.ToString();
           
            }
 
            context.Response.Redirect(this._newUrl+ qTring);
   }


ASP.NET MVC With AngularJS

 @Scripts.Render("~/bundles/angularjs")   要放在 angular.module使用之前

使用 controller的寫法

1.2
 function HelloController($scope) {
     $scope.greeting = { text: 'Hello' };
 }

1.3
var myApp = angular.module('myApp', []);

     myApp.controller('HelloController', ['$scope', function ($scope) {
         $scope.greeting = { text: 'Hello' };
     } ]);


or 

 function HelloController($scope) {
         $scope.greeting = { text: 'Hello' };
  }

// The $inject property of every controller (and pretty much every other type of object in Angular) needs to be a string array equal to the controllers arguments, only as strings
HelloController.$inject = ['$scope'];

 var myApp = angular.module('myApp', []);
 myApp.controller('HelloController', HelloController);


SPA 注意事項
1.要設定 SPA要先加入 angular-route.min.js

 //AngularJS
 bundles.Add(new ScriptBundle("~/bundles/angularjs").Include(
                        "~/Scripts/angular.min.js"
                       , "~/Scripts/angular-route.min.js"
                     
                        ));

2.設定連結
   a href="/#/routeOne"

   如果 default網頁是 Index.cshtml,可以寫成如上的連結,但如果不是,比如有一個網頁叫 SPATest.cshtml放在 Home目錄底下的話,連結修改如下:
 
   a href="/Home/SPATest/#/routeOne"

3.加上一個   <div ng-view></div>在你的 Index.cshtml (SPA的首頁)上

4.設定 angulasjs route,可儲存在 javascript檔
 
     //routing for angularjs
     var configFunction = function ($routeProvider) {
         $routeProvider.
        when('/routeOne', {
            templateUrl: '/RoutesDemo/one'
        })
        .when('/routeTwo', {
            templateUrl: '/RoutesDemo/two'
        })
       .when('/routeThree', {
            templateUrl: '/RoutesDemo/three'
        });

     }
     configFunction.$inject = ['$routeProvider'];

     myApp.config(configFunction);

5. 建立 contorller
     public class RoutesDemoController : Controller
    {
        //
        // GET: /RouttesDemo/

        public ActionResult One()
        {
            ViewBag.test = 1;
            return PartialView("SPAPartialTest");
        }

        public ActionResult Two(int donuts = 1)
        {
            ViewBag.Donuts = donuts;
            ViewBag.test = 1;
            return PartialView("Two");
        }
        public ActionResult Three()
        {
            ViewBag.test = 3;
            return PartialView("SPAPartialTest");
        }

    }

6.建立 partialview


Hands On Lab: Build a Single Page Application (SPA) with ASP.NET Web API and Angular.js

Using AngularJs, ASP.NET MVC, Web API and EntityFramework to build NLayered Single Page Web Applications

【AngularJs + ASP.NET MVC】使用AntularJs快速建立ASP.NET MVC SPA網站

Getting started with AngularJS and ASP.NET MVC - Part One
Getting started with AngularJS and ASP.NET MVC - Part Two

AngularJS 開發 ASP.NET MVC

What's the difference between “return View()” and “return PartialView()”

2014年10月29日 星期三

如何在 ASP.NET MVC 4 使用 CDN上的 java script 和 css

一般在 app_start的 BundleClass 會如下的程式碼,以讀取自己下載下來的 java script & css

 bundles.Add(new StyleBundle("~/Content/sweetalsertforbs_css").Include(
                       "~/Content/sweet-alert.css"
                       ));

 bundles.Add(new ScriptBundle("~/bundles/sweetalsertforbs_js").Include(
                       "~/Scripts/sweet-alert.js"));

如果 ASP.NET MVC要用 CDN上的資源呢,可以參考如下的作法

// BundleTable.EnableOptimizations = true;  表示在 debug mode也要使用 cnd的資源
 BundleTable.EnableOptimizations = true;

//bundles.UseCdn = true;  要存取 cdn的資源
 bundles.UseCdn = true;

//要加上 CDN的來源,一般如果 release mode使用 CDN,debug mode就使用 local的
 bundles.Add(new StyleBundle("~/Content/sweetalsertforbs_css", "//cdn.jsdelivr.net/sweetalert/0.1.2/sweet-alert.min.css").Include(
                       "~/Content/sweet-alert.css"
                       ));

bundles.Add(new ScriptBundle("~/bundles/sweetalsertforbs_js", "//cdn.jsdelivr.net/sweetalert/0.1.2/sweet-alert.min.js").Include(
                       "~/Scripts/sweet-alert.js"));

jsDeliver

參考文件

MVC 4 Part 4 - Bundles and Optimisation

2014年10月24日 星期五

jQuery getJSON()

AJAX 方面學習,今天有看到一些可以學習的的部份

jQuery.getJSON()  ,  .appendTo()

Getting Started with ASP.NET Web API 2

原本寫法
$.getJSON( "ajax/test.json", function( data ) {
var items = [];
$.each( data, function( key, val ) {
items.push( "<li id='" + key + "'>" + val + "</li>" );
});
$( "<ul/>", {
"class": "my-new-list",
html: items.join( "" )
}).appendTo( "body" );
});

1.5以後的版本可以寫成如,可用 .done來作後續 data成功回傳的動作

$(document).ready(function () {
    // Send an AJAX request
    $.getJSON(apiUrl)
        .done(function (data) {
            // On success, 'data' contains a list of products.
            $.each(data, function (key, item) {
                // Add a list item for the product.
                $('<li>', { text: formatItem(item) }).appendTo($('#products'));
            });
        });
});

var jqxhr = $.getJSON( "example.json", function() {
console.log( "success" );
}).done(function() {
console.log( "second success" );
}).fail(function() {
console.log( "error" );
}).always(function() {
console.log( "complete" );
});
jqxhr.complete(function() {
console.log( "second complete" );
});

2014年10月21日 星期二

SweetAlert for Bootstrap - A beautiful replacement for JavaScript's "alert"

連結
SweetAlert 官網
document.querySelector()說明

先把 js, css 加入後,再 javascript 程式碼加上如下程式碼, .sweet-1是指在某個 html元件宣告 class內的名稱,如 button class="btn btn-lg btn-success sweet-1" ,這樣就可以使用 SweetAlert的美麗彈出視窗了



document.querySelector('.sweet-1').onclick = function(){

swal("Here's a message!");

};




2014年9月2日 星期二

Unclean shutdown detected on MongoDB

參考文章:Recover Data after an Unexpected Shutdown

會有一個 mongod.lock的檔案產生,如果檔案大小不為 0就會無法正常開啟 mongoDB

解決方法有兩種

1.複製一份資料
   mongod --dbpath /data/db --repair --repairpath /data/db0
   再開啟新的檔案  mongod --dbpath /data/db0

2.直接蓋掉原檔
    先移除 mongod.lock
    執行 mongod --dbpath /data/db --repair   
   


2014年8月22日 星期五

用 union 取代 exists解決 performance issue

目前碰到的情況是,我有一個 table用來儲存 GL drill-down的資料,會儲存約一年的資料,約1千3百萬筆。 有一個應用就是每個部門會查詢該部門的費用,在 hr那邊會有資訊記錄登錄的使用者具有那一個部門會科,但有可能一個人員會有需求看多個部門費用,所以會有另一個 table來記錄使用可以看那些部門的部門會科值,原本的寫法為是用 exists,大約如下:

    select * from gl_drill_down_data d
    where d.dept_id = (user_dept_id)
         or (exists (select 'ex' from user_depts ud
                         where ud.user_id = p_user_id
                             and d.user_dept_id = ud.dept_id
                        )
             )

這樣的寫法在資料筆數只有百萬筆的時候沒什麼效率問題,但更多資料時就會出現很慢的情況,就算作了很好的 index也一樣,後來的解法就是用 union如下:


select d.* from gl_drill_down_data d
where d.dept_id = (user_dept_id)
union
select d.* from gl_drill_down_data d, user_depts ud
where ud.user_id = p_user_id
and d.user_dept_id = ud.dept_id

這樣效率真的差很多,可以參考看看。
                 

2014年8月6日 星期三

TechDays Taiwan 2014 - Microsoft

可以開始報名囉,希望今年我可以去~~

GV有兩筆重複的憑證號碼存在

這個發生的情況為憑證類別為海關代徵營業稅,使用者在不同發票上輸入相同的憑證號碼,資通的顧問說畫面上會提示,但允許存檔。 如果發現相同的話,如果 ap invoice 作刪除,也要順便把 GV的那一作刪除才行。

2014年7月31日 星期四

2014年7月21日 星期一

Oracle EBS R12 PO Line單價異動影響 AP會科費用產生

通常發生在倉管人員有作退料的情況下,採購使用者會來問,為什麼收料是一個單價,退料又是另一個單價,AP Invoice, Debit Memo這時會科就會出現差異,很明顯的就是在這收、退的期間內,使用者去改變 PO Line的單價了,但可能是使用者太忙忘了,還是推責任的因素,往往都不承認有作過這件事,所以可以用 DB Trigger or ERP Alert的方式,如果有針對價格或數量有更動的話,把記錄寫進到一個暫存的 table內,這樣就比較好找出問題了。   雖然 Oracle ERP有很多 bug,尤其是在 AP這一模組,但實在很不想聽到每次使用者都說是系統的問題。

2014年7月17日 星期四

Asp.net MVC 3, 4, 5的說明

這邊有一篇文章有對不同的版本作說明,如下:

ASP.NET MVC3 Vs MVC4 Vs MVC5

如果要開發 MVC 5的程式,需要 Visual Studio 2012以上的版本才行

2014年5月30日 星期五

如何讓 Procedure的 Concurrent Status可以變成 Warning 或 Error

參考文章:ERRBUF and RETCODE in Concurrent Program

 因為是 Concurrent是呼叫 Procedure的話,第一個、第二個參數為
 errbuf out varchar2  ,retcode out varchar2

所以可以利用 retcode
retcode  := 1 ERP Request Status就會是 Warning,
retcode  := 2 就會是 Error

2014年5月28日 星期三

Oracle EBS R12 Doc ID 1489862.1 R12 Generic Data Fix (GDF) Patch for COMMONLY OCCURING INVOICE ISSUES 無法解決 Mat 3

前一陣子有用 single_trx.sql找出一筆 invoice需要作 data fix,使用 ap_one_off_scripts_sel(fix).sql來解決,於更新了 patch也執行了 fix程式,但此筆的問題還是存在,而且重新執行 single_trx.sql還是會建議你用相同的 datafix 解決,後來可行的作法就是
1.先請使用者先將 invoice line作 discard後存檔
2.我再跑一次 single_trx.sql,結果發現另一個 datafix的建議 R12: Generic Data Fix (GDF) Patch - Unable to Discard PO Matched Invoice Lines [ID 982072.1]
3.執行  ap_sync_po_qty_amt_sel(fix).sql後
4.重新 match就正常了。

Spring Security OAuth2 Client anonymous 存取 Oauth2 resource

spring-projects/spring-security-oauth 在這個專案有 OAuth1, OAuth2的 Server, Client實作,在 OAuth1 Client 存取 Server resource時是可以直接存取的,但在 OAuth2 Client的設計是要先登入才能存取 Server resource,如果要直接存取的話,則會出現錯誤如下

org.springframework.security.authentication.InsufficientAuthenticationException: Authentication is required to obtain an access token (anonymous not allowed)



這邊有一邊文章 (Integrating Google Calendar into a Wicket Application) 可以達到直接存取的目的,
作法大約如下:

1.實作一 class extends AbstractAuthenticationProcessingFilter, 最主要是在

  attemptAuthentication 內產生一個 TestingAuthenticationToken,只要是作為 anonymous登入用


   public class AnoAuthenicationProcessingFilter extends AbstractAuthenticationProcessingFilter {
private static java.util.logging.Logger log1 = java.util.logging.Logger.getLogger("");

    protected AnoAuthenicationProcessingFilter() {
    //super內的參數不可為空白
        super("/login.jsp");
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
   
        //Authentication authentication = new TestingAuthenticationToken(request.getRemoteAddr(), request.getRemoteAddr(), "ROLE_ANONYMOUS");
   
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
   
    if ( authentication == null) {
            log1.log(Level.WARNING,".........establish a new tem Test token for "+ request.getRemoteAddr());
    authentication = new TestingAuthenticationToken(request.getRemoteAddr(), request.getRemoteAddr(), "ROLE_ANONYMOUS");
            authentication.setAuthenticated(true);
    }
   
   
        return getAuthenticationManager().authenticate(authentication);
     
    }

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        if (SecurityContextHolder.getContext().getAuthentication() == null) {
            SecurityContextHolder.getContext().setAuthentication(attemptAuthentication((HttpServletRequest) req, (HttpServletResponse) res));

            if (logger.isDebugEnabled()) {
                logger.debug("Populated SecurityContextHolder with dummy token: '"
                        + SecurityContextHolder.getContext().getAuthentication() + "'");
            }
        } else {
            if (logger.isDebugEnabled()) {
                logger.debug("SecurityContextHolder not populated with dummy token, as it already contained: '"
                        + SecurityContextHolder.getContext().getAuthentication() + "'");
            }
        }
   
        chain.doFilter(req, res);
    }
}

2.實作 implements AuthenticationProvider
    我希望使用者部份功能需要帳號密碼才能使用,所以在這邊有判斷 Authentication是那一種類
    別,在實作 support時就要加上可允許的 token類別

public class CattonOAuthClientProvider implements AuthenticationProvider{
private static java.util.logging.Logger log1 = java.util.logging.Logger.getLogger("");

public CattonOAuthClientProvider() {
super();
}

public Authentication authenticate(Authentication authentication)    throws AuthenticationException {
log1.log(Level.WARNING,"authentication class type............. " +authentication.getClass().toString());

        if (authentication instanceof UsernamePasswordAuthenticationToken)  {
        ‧‧‧‧‧
                ‧‧‧‧
        log1.log(Level.WARNING, "...login by account password...................");
        System.out.println("...login by account password...................");
       
       
        }else if (authentication instanceof TestingAuthenticationToken ) {
        log1.log(Level.WARNING, "...anonymous..............");
       
        } else {
        log1.log(Level.WARNING, "faile to authenicate in provder..............");
        }
       
     
       return authentication;
    }

     public boolean supports(Class authentication) {
          return TestingAuthenticationToken.class.isAssignableFrom(authentication)
       || UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);

     }
}


 3.修改 spring-servlet.xml
 
    在 custom-filter after="EXCEPTION_TRANSLATION_FILTER" ref="oauth2ClientFilter" 之前加上
    custom-filter before="ANONYMOUS_FILTER" ref="authProcessingFilter"
 
    之後再加上
    bean class="com.catton.spring.security.AnoAuthenicationProcessingFilter" id="authProcessingFilter"
property name="authenticationManager" ref="defaultAuthenticationManager"

    bean id="authenticationProvider"   class="com.catton.spring.security.provider.CattonOAuthClientProvider"

    最後再修改 authentication-manager 設定為 authentication-provider ref="authenticationProvider" 即
    可



Oracle EBS R12 AP Invoice Hold Troubleshooting

可參考如下連結:12: Invoice HOLDS: Causes and Troubleshooting [Video] (Doc ID 1472606.1)

今天有碰到使用者問我一張 invoice有一個 Matching Required的 hold,但我沒遇過,所以找到這篇文件,上面有寫到 supplier site設定上有一個參數 Unmatched Invoices 如果有打勾,代表 invoice line一定都要經過 match產生才可以,如果手動增加且沒有match就會出現這個 hold。  如果還有其它 hold的問題可以來這邊找找看如何解決。


2014年3月17日 星期一

大批付款一直無法捉取負項 AP Invoice

一般可能都是銀行帳戶沒有維護好的問題,可以先檢查 Reject Report看看被 Reject的有那些, 再來查詢 Selected Payment Schedules Report內 Unselected Scheduled Payments and Credits, 如果有出現 Credit reduces payment amount below zero的話,請先檢查該供應商所有該付的 Invoice,不管正、負, Schedule Payment內銀行帳號是否都有值或是正確的,如果沒有的話,請先維護正確,再重新跑一次看看是否問題解決了沒。

2014年2月11日 星期二

Oracle EBS R12 為何更改 AP Invoice date但 due date確不會自動更新


請至 supplier設定功能先檢查 Invoice Management ==> Term ==> Terms Date Basis是不是有設定正確,如果想要更改 invoice date後 due date就會自動更新的話,請把它設為 Invoice,其它值的話,請就參考下列的文章



參考文件:R12: How is a Payables Invoice Due Date Calculated? (Doc ID 1136143.1)